summaryrefslogtreecommitdiffstats
path: root/gnu/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/lib')
-rw-r--r--gnu/lib/Makefile5
-rw-r--r--gnu/lib/Makefile.inc8
-rw-r--r--gnu/lib/libdialog/CHANGES9
-rw-r--r--gnu/lib/libdialog/COPYING339
-rw-r--r--gnu/lib/libdialog/Makefile37
-rw-r--r--gnu/lib/libdialog/README8
-rw-r--r--gnu/lib/libdialog/TESTS/Makefile67
-rw-r--r--gnu/lib/libdialog/TESTS/check1.c82
-rw-r--r--gnu/lib/libdialog/TESTS/check2.c104
-rw-r--r--gnu/lib/libdialog/TESTS/check3.c91
-rw-r--r--gnu/lib/libdialog/TESTS/dselect.c40
-rw-r--r--gnu/lib/libdialog/TESTS/fselect.c43
-rw-r--r--gnu/lib/libdialog/TESTS/gauge.c40
-rw-r--r--gnu/lib/libdialog/TESTS/input1.c44
-rw-r--r--gnu/lib/libdialog/TESTS/menu1.c95
-rw-r--r--gnu/lib/libdialog/TESTS/menu2.c95
-rw-r--r--gnu/lib/libdialog/TESTS/menu3.c106
-rw-r--r--gnu/lib/libdialog/TESTS/msg.c41
-rw-r--r--gnu/lib/libdialog/TESTS/prgbox.c40
-rw-r--r--gnu/lib/libdialog/TESTS/radio1.c70
-rw-r--r--gnu/lib/libdialog/TESTS/radio2.c88
-rw-r--r--gnu/lib/libdialog/TESTS/radio3.c97
-rw-r--r--gnu/lib/libdialog/TESTS/text.c40
-rw-r--r--gnu/lib/libdialog/TESTS/yesno.c41
-rw-r--r--gnu/lib/libdialog/TODO36
-rw-r--r--gnu/lib/libdialog/checklist.c539
-rw-r--r--gnu/lib/libdialog/colors.h219
-rw-r--r--gnu/lib/libdialog/dialog.3391
-rw-r--r--gnu/lib/libdialog/dialog.h158
-rw-r--r--gnu/lib/libdialog/dialog.priv.h178
-rw-r--r--gnu/lib/libdialog/dir.c549
-rw-r--r--gnu/lib/libdialog/dir.h38
-rw-r--r--gnu/lib/libdialog/fselect.c400
-rw-r--r--gnu/lib/libdialog/gauge.c72
-rw-r--r--gnu/lib/libdialog/help.c194
-rw-r--r--gnu/lib/libdialog/inputbox.c190
-rw-r--r--gnu/lib/libdialog/kernel.c524
-rw-r--r--gnu/lib/libdialog/lineedit.c213
-rw-r--r--gnu/lib/libdialog/menubox.c454
-rw-r--r--gnu/lib/libdialog/msgbox.c342
-rw-r--r--gnu/lib/libdialog/notify.c50
-rw-r--r--gnu/lib/libdialog/prgbox.c148
-rw-r--r--gnu/lib/libdialog/radiolist.c533
-rw-r--r--gnu/lib/libdialog/raw_popen.c160
-rw-r--r--gnu/lib/libdialog/rc.c375
-rw-r--r--gnu/lib/libdialog/rc.h222
-rw-r--r--gnu/lib/libdialog/textbox.c694
-rw-r--r--gnu/lib/libdialog/ui_objects.c812
-rw-r--r--gnu/lib/libdialog/ui_objects.h113
-rw-r--r--gnu/lib/libdialog/yesno.c149
-rw-r--r--gnu/lib/libg++/Makefile52
-rw-r--r--gnu/lib/libg++/doc/Makefile14
-rw-r--r--gnu/lib/libgcc/Makefile95
-rw-r--r--gnu/lib/libgmp/COPYING339
-rw-r--r--gnu/lib/libgmp/COPYING.LIB481
-rw-r--r--gnu/lib/libgmp/ChangeLog3193
-rw-r--r--gnu/lib/libgmp/INSTALL154
-rw-r--r--gnu/lib/libgmp/Makefile62
-rw-r--r--gnu/lib/libgmp/Makefile.GNU289
-rw-r--r--gnu/lib/libgmp/Makefile.in210
-rw-r--r--gnu/lib/libgmp/NEWS56
-rw-r--r--gnu/lib/libgmp/PROJECTS270
-rw-r--r--gnu/lib/libgmp/README137
-rw-r--r--gnu/lib/libgmp/SPEED156
-rw-r--r--gnu/lib/libgmp/TODO184
-rw-r--r--gnu/lib/libgmp/VERSION1
-rw-r--r--gnu/lib/libgmp/_mpz_get_str.c309
-rw-r--r--gnu/lib/libgmp/_mpz_set_str.c258
-rw-r--r--gnu/lib/libgmp/alloca.c466
-rwxr-xr-xgnu/lib/libgmp/config.guess592
-rwxr-xr-xgnu/lib/libgmp/config.sub1094
-rw-r--r--gnu/lib/libgmp/config/mt-linux1
-rw-r--r--gnu/lib/libgmp/config/mt-m881101
-rw-r--r--gnu/lib/libgmp/config/mt-sprc8-gcc1
-rw-r--r--gnu/lib/libgmp/config/mt-supspc-gcc1
-rwxr-xr-xgnu/lib/libgmp/configure1263
-rw-r--r--gnu/lib/libgmp/configure.in35
-rw-r--r--gnu/lib/libgmp/cre-conv-tab.c140
-rw-r--r--gnu/lib/libgmp/cre-mparam.c121
-rw-r--r--gnu/lib/libgmp/cre-stddefh.c42
-rw-r--r--gnu/lib/libgmp/demos/factorize.c233
-rw-r--r--gnu/lib/libgmp/doc/Makefile7
-rw-r--r--gnu/lib/libgmp/extract-double.c160
-rw-r--r--gnu/lib/libgmp/gmp-impl.h367
-rw-r--r--gnu/lib/libgmp/gmp.h632
-rw-r--r--gnu/lib/libgmp/gmp.info-11283
-rw-r--r--gnu/lib/libgmp/gmp.info-21035
-rw-r--r--gnu/lib/libgmp/gmp.info-3259
-rw-r--r--gnu/lib/libgmp/gmp.texi2697
-rw-r--r--gnu/lib/libgmp/insert-double.c70
-rwxr-xr-xgnu/lib/libgmp/install.sh238
-rw-r--r--gnu/lib/libgmp/itom.c53
-rw-r--r--gnu/lib/libgmp/longlong.h1404
-rwxr-xr-xgnu/lib/libgmp/make.bat315
-rw-r--r--gnu/lib/libgmp/mdiv.c38
-rw-r--r--gnu/lib/libgmp/memory.c97
-rw-r--r--gnu/lib/libgmp/mfree.c35
-rw-r--r--gnu/lib/libgmp/min.c64
-rwxr-xr-xgnu/lib/libgmp/mkinstalldirs32
-rw-r--r--gnu/lib/libgmp/mout.c42
-rwxr-xr-xgnu/lib/libgmp/move-if-change15
-rw-r--r--gnu/lib/libgmp/move.c45
-rw-r--r--gnu/lib/libgmp/mp.h141
-rw-r--r--gnu/lib/libgmp/mp_bpl.c4
-rw-r--r--gnu/lib/libgmp/mp_clz_tab.c40
-rw-r--r--gnu/lib/libgmp/mp_set_fns.c48
-rw-r--r--gnu/lib/libgmp/mpbsd/Makefile.in84
-rw-r--r--gnu/lib/libgmp/mpbsd/configure.in20
-rw-r--r--gnu/lib/libgmp/mpbsd/itom.c54
-rw-r--r--gnu/lib/libgmp/mpbsd/mdiv.c39
-rw-r--r--gnu/lib/libgmp/mpbsd/mfree.c36
-rw-r--r--gnu/lib/libgmp/mpbsd/min.c89
-rw-r--r--gnu/lib/libgmp/mpbsd/mout.c96
-rw-r--r--gnu/lib/libgmp/mpbsd/move.c46
-rw-r--r--gnu/lib/libgmp/mpbsd/mtox.c81
-rw-r--r--gnu/lib/libgmp/mpbsd/realloc.c44
-rw-r--r--gnu/lib/libgmp/mpbsd/sdiv.c77
-rw-r--r--gnu/lib/libgmp/mpbsd/xtom.c110
-rw-r--r--gnu/lib/libgmp/mpf/Makefile.in115
-rw-r--r--gnu/lib/libgmp/mpf/abs.c56
-rw-r--r--gnu/lib/libgmp/mpf/add.c180
-rw-r--r--gnu/lib/libgmp/mpf/add_ui.c151
-rw-r--r--gnu/lib/libgmp/mpf/clear.c35
-rw-r--r--gnu/lib/libgmp/mpf/cmp.c114
-rw-r--r--gnu/lib/libgmp/mpf/cmp_si.c98
-rw-r--r--gnu/lib/libgmp/mpf/cmp_ui.c80
-rw-r--r--gnu/lib/libgmp/mpf/configure.in12
-rw-r--r--gnu/lib/libgmp/mpf/div.c144
-rw-r--r--gnu/lib/libgmp/mpf/div_2exp.c79
-rw-r--r--gnu/lib/libgmp/mpf/div_ui.c91
-rw-r--r--gnu/lib/libgmp/mpf/dump.c43
-rw-r--r--gnu/lib/libgmp/mpf/eq.c121
-rw-r--r--gnu/lib/libgmp/mpf/get_d.c54
-rw-r--r--gnu/lib/libgmp/mpf/get_prc.c34
-rw-r--r--gnu/lib/libgmp/mpf/get_str.c500
-rw-r--r--gnu/lib/libgmp/mpf/init.c38
-rw-r--r--gnu/lib/libgmp/mpf/init2.c41
-rw-r--r--gnu/lib/libgmp/mpf/inp_str.c89
-rw-r--r--gnu/lib/libgmp/mpf/iset.c59
-rw-r--r--gnu/lib/libgmp/mpf/iset_d.c39
-rw-r--r--gnu/lib/libgmp/mpf/iset_si.c55
-rw-r--r--gnu/lib/libgmp/mpf/iset_str.c40
-rw-r--r--gnu/lib/libgmp/mpf/iset_ui.c40
-rw-r--r--gnu/lib/libgmp/mpf/mul.c94
-rw-r--r--gnu/lib/libgmp/mpf/mul_2exp.c89
-rw-r--r--gnu/lib/libgmp/mpf/mul_ui.c74
-rw-r--r--gnu/lib/libgmp/mpf/neg.c59
-rw-r--r--gnu/lib/libgmp/mpf/out_str.c89
-rw-r--r--gnu/lib/libgmp/mpf/random2.c65
-rw-r--r--gnu/lib/libgmp/mpf/reldiff.c52
-rw-r--r--gnu/lib/libgmp/mpf/set.c53
-rw-r--r--gnu/lib/libgmp/mpf/set_d.c47
-rw-r--r--gnu/lib/libgmp/mpf/set_dfl_prec.c40
-rw-r--r--gnu/lib/libgmp/mpf/set_prc.c57
-rw-r--r--gnu/lib/libgmp/mpf/set_prc_raw.c39
-rw-r--r--gnu/lib/libgmp/mpf/set_q.c170
-rw-r--r--gnu/lib/libgmp/mpf/set_si.c51
-rw-r--r--gnu/lib/libgmp/mpf/set_str.c302
-rw-r--r--gnu/lib/libgmp/mpf/set_ui.c45
-rw-r--r--gnu/lib/libgmp/mpf/set_z.c54
-rw-r--r--gnu/lib/libgmp/mpf/size.c35
-rw-r--r--gnu/lib/libgmp/mpf/sqrt.c75
-rw-r--r--gnu/lib/libgmp/mpf/sqrt_ui.c61
-rw-r--r--gnu/lib/libgmp/mpf/sub.c402
-rw-r--r--gnu/lib/libgmp/mpf/sub_ui.c49
-rw-r--r--gnu/lib/libgmp/mpf/tests/Makefile.in75
-rw-r--r--gnu/lib/libgmp/mpf/tests/configure.in11
-rw-r--r--gnu/lib/libgmp/mpf/tests/ref.c203
-rw-r--r--gnu/lib/libgmp/mpf/tests/reuse.c186
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-add.c117
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-conv.c120
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-dm2exp.c101
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-muldiv.c161
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-sqrt.c103
-rw-r--r--gnu/lib/libgmp/mpf/tests/t-sub.c122
-rw-r--r--gnu/lib/libgmp/mpf/ui_div.c131
-rw-r--r--gnu/lib/libgmp/mpf/ui_sub.c334
-rw-r--r--gnu/lib/libgmp/mpn/Makefile.in92
-rw-r--r--gnu/lib/libgmp/mpn/README15
-rw-r--r--gnu/lib/libgmp/mpn/bsd.h5
-rw-r--r--gnu/lib/libgmp/mpn/config/t-oldgas1
-rw-r--r--gnu/lib/libgmp/mpn/config/t-ppc-aix1
-rw-r--r--gnu/lib/libgmp/mpn/config/t-pwr-aix1
-rw-r--r--gnu/lib/libgmp/mpn/configure.in178
-rw-r--r--gnu/lib/libgmp/mpn/generic/add_n.c62
-rw-r--r--gnu/lib/libgmp/mpn/generic/addmul_1.c65
-rw-r--r--gnu/lib/libgmp/mpn/generic/bdivmod.c129
-rw-r--r--gnu/lib/libgmp/mpn/generic/cmp.c56
-rw-r--r--gnu/lib/libgmp/mpn/generic/divmod_1.c208
-rw-r--r--gnu/lib/libgmp/mpn/generic/divrem.c245
-rw-r--r--gnu/lib/libgmp/mpn/generic/divrem_1.c58
-rw-r--r--gnu/lib/libgmp/mpn/generic/dump.c20
-rw-r--r--gnu/lib/libgmp/mpn/generic/gcd.c402
-rw-r--r--gnu/lib/libgmp/mpn/generic/gcd_1.c73
-rw-r--r--gnu/lib/libgmp/mpn/generic/gcdext.c441
-rw-r--r--gnu/lib/libgmp/mpn/generic/get_str.c211
-rw-r--r--gnu/lib/libgmp/mpn/generic/gmp-mparam.h27
-rw-r--r--gnu/lib/libgmp/mpn/generic/hamdist.c88
-rw-r--r--gnu/lib/libgmp/mpn/generic/inlines.c3
-rw-r--r--gnu/lib/libgmp/mpn/generic/lshift.c87
-rw-r--r--gnu/lib/libgmp/mpn/generic/mod_1.c197
-rw-r--r--gnu/lib/libgmp/mpn/generic/mul.c152
-rw-r--r--gnu/lib/libgmp/mpn/generic/mul_1.c59
-rw-r--r--gnu/lib/libgmp/mpn/generic/mul_n.c401
-rw-r--r--gnu/lib/libgmp/mpn/generic/perfsqr.c138
-rw-r--r--gnu/lib/libgmp/mpn/generic/popcount.c87
-rw-r--r--gnu/lib/libgmp/mpn/generic/pre_mod_1.c69
-rw-r--r--gnu/lib/libgmp/mpn/generic/random2.c93
-rw-r--r--gnu/lib/libgmp/mpn/generic/rshift.c88
-rw-r--r--gnu/lib/libgmp/mpn/generic/scan0.c62
-rw-r--r--gnu/lib/libgmp/mpn/generic/scan1.c62
-rw-r--r--gnu/lib/libgmp/mpn/generic/set_str.c154
-rw-r--r--gnu/lib/libgmp/mpn/generic/sqrtrem.c498
-rw-r--r--gnu/lib/libgmp/mpn/generic/sub_n.c62
-rw-r--r--gnu/lib/libgmp/mpn/generic/submul_1.c65
-rw-r--r--gnu/lib/libgmp/mpn/generic/udiv_w_sdiv.c125
-rw-r--r--gnu/lib/libgmp/mpn/mp_bases.c549
-rw-r--r--gnu/lib/libgmp/mpn/tests/add_n.c211
-rw-r--r--gnu/lib/libgmp/mpn/tests/addmul_1.c223
-rw-r--r--gnu/lib/libgmp/mpn/tests/divmod_1.c120
-rw-r--r--gnu/lib/libgmp/mpn/tests/divrem.c129
-rw-r--r--gnu/lib/libgmp/mpn/tests/lshift.c226
-rw-r--r--gnu/lib/libgmp/mpn/tests/mul_1.c212
-rw-r--r--gnu/lib/libgmp/mpn/tests/rshift.c227
-rw-r--r--gnu/lib/libgmp/mpn/tests/sub_n.c211
-rw-r--r--gnu/lib/libgmp/mpn/tests/submul_1.c218
-rw-r--r--gnu/lib/libgmp/mpn/tests/tst-addsub.c164
-rw-r--r--gnu/lib/libgmp/mpn/x86/add_n.S106
-rw-r--r--gnu/lib/libgmp/mpn/x86/addmul_1.S76
-rw-r--r--gnu/lib/libgmp/mpn/x86/lshift.S85
-rw-r--r--gnu/lib/libgmp/mpn/x86/mul_1.S75
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/README26
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/add_n.S130
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/addmul_1.S83
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/lshift.S217
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/mul_1.S79
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/rshift.S217
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/sub_n.S130
-rw-r--r--gnu/lib/libgmp/mpn/x86/pentium/submul_1.S83
-rw-r--r--gnu/lib/libgmp/mpn/x86/rshift.S87
-rw-r--r--gnu/lib/libgmp/mpn/x86/sub_n.S106
-rw-r--r--gnu/lib/libgmp/mpn/x86/submul_1.S76
-rw-r--r--gnu/lib/libgmp/mpn/x86/syntax.h62
-rw-r--r--gnu/lib/libgmp/mpn_add.c141
-rw-r--r--gnu/lib/libgmp/mpn_cmp.c52
-rw-r--r--gnu/lib/libgmp/mpn_div.c321
-rw-r--r--gnu/lib/libgmp/mpn_dm_1.c185
-rw-r--r--gnu/lib/libgmp/mpn_lshift.c83
-rw-r--r--gnu/lib/libgmp/mpn_mod_1.c104
-rw-r--r--gnu/lib/libgmp/mpn_mul.c414
-rw-r--r--gnu/lib/libgmp/mpn_rshift.c90
-rw-r--r--gnu/lib/libgmp/mpn_rshiftci.c86
-rw-r--r--gnu/lib/libgmp/mpn_sqrt.c479
-rw-r--r--gnu/lib/libgmp/mpn_sub.c162
-rw-r--r--gnu/lib/libgmp/mpq/Makefile.in81
-rw-r--r--gnu/lib/libgmp/mpq/add.c85
-rw-r--r--gnu/lib/libgmp/mpq/canonicalize.c53
-rw-r--r--gnu/lib/libgmp/mpq/clear.c37
-rw-r--r--gnu/lib/libgmp/mpq/cmp.c120
-rw-r--r--gnu/lib/libgmp/mpq/cmp_ui.c84
-rw-r--r--gnu/lib/libgmp/mpq/configure.in12
-rw-r--r--gnu/lib/libgmp/mpq/div.c93
-rw-r--r--gnu/lib/libgmp/mpq/equal.c43
-rw-r--r--gnu/lib/libgmp/mpq/get_d.c151
-rw-r--r--gnu/lib/libgmp/mpq/get_den.c41
-rw-r--r--gnu/lib/libgmp/mpq/get_num.c42
-rw-r--r--gnu/lib/libgmp/mpq/init.c40
-rw-r--r--gnu/lib/libgmp/mpq/inv.c75
-rw-r--r--gnu/lib/libgmp/mpq/mul.c79
-rw-r--r--gnu/lib/libgmp/mpq/neg.c36
-rw-r--r--gnu/lib/libgmp/mpq/set.c49
-rw-r--r--gnu/lib/libgmp/mpq/set_den.c42
-rw-r--r--gnu/lib/libgmp/mpq/set_num.c42
-rw-r--r--gnu/lib/libgmp/mpq/set_si.c54
-rw-r--r--gnu/lib/libgmp/mpq/set_ui.c50
-rw-r--r--gnu/lib/libgmp/mpq/set_z.c46
-rw-r--r--gnu/lib/libgmp/mpq/sub.c85
-rw-r--r--gnu/lib/libgmp/mpq/tests/Makefile.in48
-rw-r--r--gnu/lib/libgmp/mpq/tests/configure.in11
-rw-r--r--gnu/lib/libgmp/mpq/tests/t-cmp.c109
-rw-r--r--gnu/lib/libgmp/mpq/tests/t-cmp_ui.c102
-rw-r--r--gnu/lib/libgmp/mpq/tests/t-get_d.c88
-rw-r--r--gnu/lib/libgmp/mpq_add.c85
-rw-r--r--gnu/lib/libgmp/mpq_clear.c34
-rw-r--r--gnu/lib/libgmp/mpq_cmp.c76
-rw-r--r--gnu/lib/libgmp/mpq_div.c92
-rw-r--r--gnu/lib/libgmp/mpq_get_den.c40
-rw-r--r--gnu/lib/libgmp/mpq_get_num.c41
-rw-r--r--gnu/lib/libgmp/mpq_init.c39
-rw-r--r--gnu/lib/libgmp/mpq_inv.c74
-rw-r--r--gnu/lib/libgmp/mpq_mul.c78
-rw-r--r--gnu/lib/libgmp/mpq_neg.c35
-rw-r--r--gnu/lib/libgmp/mpq_set.c48
-rw-r--r--gnu/lib/libgmp/mpq_set_den.c46
-rw-r--r--gnu/lib/libgmp/mpq_set_num.c41
-rw-r--r--gnu/lib/libgmp/mpq_set_si.c76
-rw-r--r--gnu/lib/libgmp/mpq_set_ui.c73
-rw-r--r--gnu/lib/libgmp/mpq_sub.c85
-rw-r--r--gnu/lib/libgmp/mpz/Makefile.in180
-rw-r--r--gnu/lib/libgmp/mpz/abs.c51
-rw-r--r--gnu/lib/libgmp/mpz/add.c120
-rw-r--r--gnu/lib/libgmp/mpz/add_ui.c84
-rw-r--r--gnu/lib/libgmp/mpz/and.c278
-rw-r--r--gnu/lib/libgmp/mpz/array_init.c48
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_q.c51
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_q_ui.c64
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_qr.c62
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_qr_ui.c68
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_r.c59
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_r_ui.c54
-rw-r--r--gnu/lib/libgmp/mpz/cdiv_ui.c50
-rw-r--r--gnu/lib/libgmp/mpz/clear.c35
-rw-r--r--gnu/lib/libgmp/mpz/clrbit.c114
-rw-r--r--gnu/lib/libgmp/mpz/cmp.c75
-rw-r--r--gnu/lib/libgmp/mpz/cmp_si.c66
-rw-r--r--gnu/lib/libgmp/mpz/cmp_ui.c56
-rw-r--r--gnu/lib/libgmp/mpz/com.c93
-rw-r--r--gnu/lib/libgmp/mpz/configure.in12
-rw-r--r--gnu/lib/libgmp/mpz/divexact.c112
-rw-r--r--gnu/lib/libgmp/mpz/dmincl.c201
-rw-r--r--gnu/lib/libgmp/mpz/fac_ui.c157
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_q.c51
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_q_2exp.c94
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_q_ui.c62
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_qr.c62
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_qr_ui.c66
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_r.c58
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_r_2exp.c88
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_r_ui.c52
-rw-r--r--gnu/lib/libgmp/mpz/fdiv_ui.c48
-rw-r--r--gnu/lib/libgmp/mpz/gcd.c178
-rw-r--r--gnu/lib/libgmp/mpz/gcd_ui.c64
-rw-r--r--gnu/lib/libgmp/mpz/gcdext.c88
-rw-r--r--gnu/lib/libgmp/mpz/get_d.c54
-rw-r--r--gnu/lib/libgmp/mpz/get_si.c43
-rw-r--r--gnu/lib/libgmp/mpz/get_str.c118
-rw-r--r--gnu/lib/libgmp/mpz/get_ui.c37
-rw-r--r--gnu/lib/libgmp/mpz/getlimbn.c38
-rw-r--r--gnu/lib/libgmp/mpz/hamdist.c62
-rw-r--r--gnu/lib/libgmp/mpz/init.c36
-rw-r--r--gnu/lib/libgmp/mpz/inp_raw.c101
-rw-r--r--gnu/lib/libgmp/mpz/inp_str.c138
-rw-r--r--gnu/lib/libgmp/mpz/invert.c43
-rw-r--r--gnu/lib/libgmp/mpz/ior.c243
-rw-r--r--gnu/lib/libgmp/mpz/iset.c49
-rw-r--r--gnu/lib/libgmp/mpz/iset_d.c39
-rw-r--r--gnu/lib/libgmp/mpz/iset_si.c49
-rw-r--r--gnu/lib/libgmp/mpz/iset_str.c44
-rw-r--r--gnu/lib/libgmp/mpz/iset_ui.c39
-rw-r--r--gnu/lib/libgmp/mpz/jacobi.c53
-rw-r--r--gnu/lib/libgmp/mpz/legendre.c184
-rw-r--r--gnu/lib/libgmp/mpz/mod.c63
-rw-r--r--gnu/lib/libgmp/mpz/mul.c127
-rw-r--r--gnu/lib/libgmp/mpz/mul_2exp.c76
-rw-r--r--gnu/lib/libgmp/mpz/mul_ui.c64
-rw-r--r--gnu/lib/libgmp/mpz/neg.c53
-rw-r--r--gnu/lib/libgmp/mpz/out_raw.c89
-rw-r--r--gnu/lib/libgmp/mpz/out_str.c108
-rw-r--r--gnu/lib/libgmp/mpz/perfsqr.c41
-rw-r--r--gnu/lib/libgmp/mpz/popcount.c42
-rw-r--r--gnu/lib/libgmp/mpz/pow_ui.c129
-rw-r--r--gnu/lib/libgmp/mpz/powm.c276
-rw-r--r--gnu/lib/libgmp/mpz/powm_ui.c234
-rw-r--r--gnu/lib/libgmp/mpz/pprime_p.c115
-rw-r--r--gnu/lib/libgmp/mpz/random.c56
-rw-r--r--gnu/lib/libgmp/mpz/random2.c48
-rw-r--r--gnu/lib/libgmp/mpz/realloc.c52
-rw-r--r--gnu/lib/libgmp/mpz/scan0.c35
-rw-r--r--gnu/lib/libgmp/mpz/scan1.c35
-rw-r--r--gnu/lib/libgmp/mpz/set.c48
-rw-r--r--gnu/lib/libgmp/mpz/set_d.c93
-rw-r--r--gnu/lib/libgmp/mpz/set_f.c64
-rw-r--r--gnu/lib/libgmp/mpz/set_q.c36
-rw-r--r--gnu/lib/libgmp/mpz/set_si.c48
-rw-r--r--gnu/lib/libgmp/mpz/set_str.c132
-rw-r--r--gnu/lib/libgmp/mpz/set_ui.c43
-rw-r--r--gnu/lib/libgmp/mpz/setbit.c113
-rw-r--r--gnu/lib/libgmp/mpz/size.c35
-rw-r--r--gnu/lib/libgmp/mpz/sizeinbase.c60
-rw-r--r--gnu/lib/libgmp/mpz/sqrt.c85
-rw-r--r--gnu/lib/libgmp/mpz/sqrtrem.c107
-rw-r--r--gnu/lib/libgmp/mpz/sub.c120
-rw-r--r--gnu/lib/libgmp/mpz/sub_ui.c84
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_q.c133
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_q_2exp.c68
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_q_ui.c63
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_qr.c39
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_qr_ui.c78
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_r.c37
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_r_2exp.c79
-rw-r--r--gnu/lib/libgmp/mpz/tdiv_r_ui.c64
-rw-r--r--gnu/lib/libgmp/mpz/tests/Makefile.in126
-rw-r--r--gnu/lib/libgmp/mpz/tests/configure.in11
-rw-r--r--gnu/lib/libgmp/mpz/tests/convert.c80
-rw-r--r--gnu/lib/libgmp/mpz/tests/dive.c87
-rw-r--r--gnu/lib/libgmp/mpz/tests/io-binary.c76
-rw-r--r--gnu/lib/libgmp/mpz/tests/io.c86
-rw-r--r--gnu/lib/libgmp/mpz/tests/logic.c103
-rw-r--r--gnu/lib/libgmp/mpz/tests/reuse.c135
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-fdiv.c118
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c117
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-gcd.c132
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-gcd2.c137
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-mul.c261
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-powm.c125
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-powm_ui.c120
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-sqrtrem.c98
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-tdiv.c118
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c117
-rw-r--r--gnu/lib/libgmp/mpz/ui_pow_ui.c111
-rw-r--r--gnu/lib/libgmp/mpz_abs.c44
-rw-r--r--gnu/lib/libgmp/mpz_add.c121
-rw-r--r--gnu/lib/libgmp/mpz_add_ui.c84
-rw-r--r--gnu/lib/libgmp/mpz_and.c267
-rw-r--r--gnu/lib/libgmp/mpz_clear.c34
-rw-r--r--gnu/lib/libgmp/mpz_clrbit.c124
-rw-r--r--gnu/lib/libgmp/mpz_cmp.c84
-rw-r--r--gnu/lib/libgmp/mpz_cmp_si.c62
-rw-r--r--gnu/lib/libgmp/mpz_cmp_ui.c52
-rw-r--r--gnu/lib/libgmp/mpz_com.c96
-rw-r--r--gnu/lib/libgmp/mpz_div.c117
-rw-r--r--gnu/lib/libgmp/mpz_div_2exp.c53
-rw-r--r--gnu/lib/libgmp/mpz_div_ui.c65
-rw-r--r--gnu/lib/libgmp/mpz_dm.c38
-rw-r--r--gnu/lib/libgmp/mpz_dm_ui.c81
-rw-r--r--gnu/lib/libgmp/mpz_dmincl.c172
-rw-r--r--gnu/lib/libgmp/mpz_fac_ui.c156
-rw-r--r--gnu/lib/libgmp/mpz_gcd.c169
-rw-r--r--gnu/lib/libgmp/mpz_gcdext.c80
-rw-r--r--gnu/lib/libgmp/mpz_get_si.c40
-rw-r--r--gnu/lib/libgmp/mpz_get_str.c39
-rw-r--r--gnu/lib/libgmp/mpz_get_ui.c36
-rw-r--r--gnu/lib/libgmp/mpz_init.c35
-rw-r--r--gnu/lib/libgmp/mpz_inp_raw.c72
-rw-r--r--gnu/lib/libgmp/mpz_inp_str.c105
-rw-r--r--gnu/lib/libgmp/mpz_ior.c242
-rw-r--r--gnu/lib/libgmp/mpz_iset.c45
-rw-r--r--gnu/lib/libgmp/mpz_iset_si.c48
-rw-r--r--gnu/lib/libgmp/mpz_iset_str.c42
-rw-r--r--gnu/lib/libgmp/mpz_iset_ui.c43
-rw-r--r--gnu/lib/libgmp/mpz_mdiv.c52
-rw-r--r--gnu/lib/libgmp/mpz_mdiv_ui.c43
-rw-r--r--gnu/lib/libgmp/mpz_mdm.c64
-rw-r--r--gnu/lib/libgmp/mpz_mdm_ui.c58
-rw-r--r--gnu/lib/libgmp/mpz_mmod.c60
-rw-r--r--gnu/lib/libgmp/mpz_mmod_ui.c52
-rw-r--r--gnu/lib/libgmp/mpz_mod.c36
-rw-r--r--gnu/lib/libgmp/mpz_mod_2exp.c82
-rw-r--r--gnu/lib/libgmp/mpz_mod_ui.c65
-rw-r--r--gnu/lib/libgmp/mpz_mul.c114
-rw-r--r--gnu/lib/libgmp/mpz_mul_2exp.c68
-rw-r--r--gnu/lib/libgmp/mpz_mul_ui.c78
-rw-r--r--gnu/lib/libgmp/mpz_neg.c46
-rw-r--r--gnu/lib/libgmp/mpz_out_raw.c55
-rw-r--r--gnu/lib/libgmp/mpz_out_str.c45
-rw-r--r--gnu/lib/libgmp/mpz_perfsqr.c118
-rw-r--r--gnu/lib/libgmp/mpz_pow_ui.c110
-rw-r--r--gnu/lib/libgmp/mpz_powm.c251
-rw-r--r--gnu/lib/libgmp/mpz_powm_ui.c219
-rw-r--r--gnu/lib/libgmp/mpz_pprime_p.c108
-rw-r--r--gnu/lib/libgmp/mpz_random.c68
-rw-r--r--gnu/lib/libgmp/mpz_random2.c88
-rw-r--r--gnu/lib/libgmp/mpz_realloc.c50
-rw-r--r--gnu/lib/libgmp/mpz_set.c45
-rw-r--r--gnu/lib/libgmp/mpz_set_si.c47
-rw-r--r--gnu/lib/libgmp/mpz_set_str.c41
-rw-r--r--gnu/lib/libgmp/mpz_set_ui.c42
-rw-r--r--gnu/lib/libgmp/mpz_size.c34
-rw-r--r--gnu/lib/libgmp/mpz_sizeinb.c59
-rw-r--r--gnu/lib/libgmp/mpz_sqrt.c87
-rw-r--r--gnu/lib/libgmp/mpz_sqrtrem.c105
-rw-r--r--gnu/lib/libgmp/mpz_sub.c117
-rw-r--r--gnu/lib/libgmp/mpz_sub_ui.c84
-rw-r--r--gnu/lib/libgmp/mtox.c37
-rw-r--r--gnu/lib/libgmp/sdiv.c76
-rw-r--r--gnu/lib/libgmp/stack-alloc.c108
-rw-r--r--gnu/lib/libgmp/stack-alloc.h56
-rw-r--r--gnu/lib/libgmp/tests/Makefile66
-rw-r--r--gnu/lib/libgmp/tests/Makefile.GNU64
-rw-r--r--gnu/lib/libgmp/tests/tst-convert.c80
-rw-r--r--gnu/lib/libgmp/tests/tst-dm.c117
-rw-r--r--gnu/lib/libgmp/tests/tst-dm_ui.c116
-rw-r--r--gnu/lib/libgmp/tests/tst-gcd.c131
-rw-r--r--gnu/lib/libgmp/tests/tst-mdm.c117
-rw-r--r--gnu/lib/libgmp/tests/tst-mdm_ui.c116
-rw-r--r--gnu/lib/libgmp/tests/tst-mul.c261
-rw-r--r--gnu/lib/libgmp/tests/tst-pow_ui.c120
-rw-r--r--gnu/lib/libgmp/tests/tst-sqrtrem.c97
-rw-r--r--gnu/lib/libgmp/tests/urandom.h17
-rw-r--r--gnu/lib/libgmp/texinfo.tex4585
-rw-r--r--gnu/lib/libgmp/urandom.h64
-rw-r--r--gnu/lib/libgmp/version.c1
-rw-r--r--gnu/lib/libgmp/xtom.c41
-rw-r--r--gnu/lib/libmp/Makefile42
-rw-r--r--gnu/lib/libobjc/Makefile33
-rw-r--r--gnu/lib/libreadline/COPYING257
-rw-r--r--gnu/lib/libreadline/ChangeLog403
-rw-r--r--gnu/lib/libreadline/Makefile26
-rw-r--r--gnu/lib/libreadline/README6
-rw-r--r--gnu/lib/libreadline/README.8bit6
-rw-r--r--gnu/lib/libreadline/STANDALONE31
-rw-r--r--gnu/lib/libreadline/VERSION1
-rw-r--r--gnu/lib/libreadline/ansi_stdlib.h41
-rw-r--r--gnu/lib/libreadline/bind.c1487
-rw-r--r--gnu/lib/libreadline/chardefs.h122
-rw-r--r--gnu/lib/libreadline/complete.c1459
-rw-r--r--gnu/lib/libreadline/config.h71
-rw-r--r--gnu/lib/libreadline/display.c1276
-rw-r--r--gnu/lib/libreadline/doc/Makefile6
-rw-r--r--gnu/lib/libreadline/doc/history.texinfo113
-rw-r--r--gnu/lib/libreadline/doc/hstech.texinfo489
-rw-r--r--gnu/lib/libreadline/doc/hsuser.texinfo198
-rw-r--r--gnu/lib/libreadline/doc/readline.texinfo111
-rw-r--r--gnu/lib/libreadline/doc/rltech.texinfo1406
-rw-r--r--gnu/lib/libreadline/doc/rluser.texinfo875
-rw-r--r--gnu/lib/libreadline/emacs_keymap.c885
-rw-r--r--gnu/lib/libreadline/examples/Inputrc65
-rw-r--r--gnu/lib/libreadline/examples/Makefile12
-rw-r--r--gnu/lib/libreadline/examples/fileman.c425
-rw-r--r--gnu/lib/libreadline/examples/histexamp.c82
-rw-r--r--gnu/lib/libreadline/examples/manexamp.c94
-rw-r--r--gnu/lib/libreadline/funmap.c299
-rw-r--r--gnu/lib/libreadline/history.c2218
-rw-r--r--gnu/lib/libreadline/history.h181
-rw-r--r--gnu/lib/libreadline/isearch.c378
-rw-r--r--gnu/lib/libreadline/keymaps.c200
-rw-r--r--gnu/lib/libreadline/keymaps.h95
-rw-r--r--gnu/lib/libreadline/memalloc.h56
-rw-r--r--gnu/lib/libreadline/parens.c130
-rw-r--r--gnu/lib/libreadline/posixstat.h149
-rw-r--r--gnu/lib/libreadline/readline.31216
-rw-r--r--gnu/lib/libreadline/readline.c3539
-rw-r--r--gnu/lib/libreadline/readline.h290
-rw-r--r--gnu/lib/libreadline/rlconf.h57
-rw-r--r--gnu/lib/libreadline/rldefs.h212
-rw-r--r--gnu/lib/libreadline/rltty.c705
-rw-r--r--gnu/lib/libreadline/search.c370
-rw-r--r--gnu/lib/libreadline/signals.c287
-rw-r--r--gnu/lib/libreadline/tilde.c380
-rw-r--r--gnu/lib/libreadline/tilde.h38
-rw-r--r--gnu/lib/libreadline/vi_keymap.c877
-rw-r--r--gnu/lib/libreadline/vi_mode.c1329
-rw-r--r--gnu/lib/libreadline/xmalloc.c78
-rw-r--r--gnu/lib/libregex/AUTHORS10
-rw-r--r--gnu/lib/libregex/COPYING339
-rw-r--r--gnu/lib/libregex/ChangeLog3030
-rw-r--r--gnu/lib/libregex/INSTALL117
-rw-r--r--gnu/lib/libregex/Makefile15
-rw-r--r--gnu/lib/libregex/Makefile.gnu99
-rw-r--r--gnu/lib/libregex/Makefile.in98
-rw-r--r--gnu/lib/libregex/NEWS62
-rw-r--r--gnu/lib/libregex/README60
-rw-r--r--gnu/lib/libregex/VERSION3
-rw-r--r--gnu/lib/libregex/config.status59
-rw-r--r--gnu/lib/libregex/configure462
-rw-r--r--gnu/lib/libregex/configure.in23
-rw-r--r--gnu/lib/libregex/doc/Makefile9
-rw-r--r--gnu/lib/libregex/doc/include.awk19
-rw-r--r--gnu/lib/libregex/doc/xregex.texi3021
-rw-r--r--gnu/lib/libregex/regex.c5086
-rw-r--r--gnu/lib/libregex/regex.h505
-rw-r--r--gnu/lib/libregex/test/ChangeLog77
-rw-r--r--gnu/lib/libregex/test/Makefile171
-rw-r--r--gnu/lib/libregex/test/Makefile.in170
-rw-r--r--gnu/lib/libregex/test/alloca.c194
-rw-r--r--gnu/lib/libregex/test/bsd-interf.c38
-rw-r--r--gnu/lib/libregex/test/debugmalloc.c273
-rw-r--r--gnu/lib/libregex/test/emacsmalloc.c844
-rw-r--r--gnu/lib/libregex/test/fileregex.c77
-rw-r--r--gnu/lib/libregex/test/g++malloc.c1288
-rw-r--r--gnu/lib/libregex/test/getpagesize.h25
-rw-r--r--gnu/lib/libregex/test/iregex.c164
-rw-r--r--gnu/lib/libregex/test/main.c49
-rw-r--r--gnu/lib/libregex/test/malloc-test.c47
-rw-r--r--gnu/lib/libregex/test/other.c503
-rw-r--r--gnu/lib/libregex/test/printchar.c14
-rw-r--r--gnu/lib/libregex/test/psx-basic.c253
-rw-r--r--gnu/lib/libregex/test/psx-extend.c1244
-rw-r--r--gnu/lib/libregex/test/psx-generic.c336
-rw-r--r--gnu/lib/libregex/test/psx-group.c440
-rw-r--r--gnu/lib/libregex/test/psx-interf.c624
-rw-r--r--gnu/lib/libregex/test/psx-interv.c140
-rw-r--r--gnu/lib/libregex/test/regexcpp.sed8
-rw-r--r--gnu/lib/libregex/test/syntax.skel74
-rw-r--r--gnu/lib/libregex/test/test.c782
-rw-r--r--gnu/lib/libregex/test/test.h141
-rw-r--r--gnu/lib/libregex/test/tregress.c464
-rw-r--r--gnu/lib/libregex/test/upcase.c39
-rw-r--r--gnu/lib/libregex/test/xmalloc.c21
-rw-r--r--gnu/lib/libstdc++/Makefile286
-rw-r--r--gnu/lib/libstdc++/_G_config.h78
591 files changed, 115585 insertions, 0 deletions
diff --git a/gnu/lib/Makefile b/gnu/lib/Makefile
new file mode 100644
index 0000000..d540430
--- /dev/null
+++ b/gnu/lib/Makefile
@@ -0,0 +1,5 @@
+# $Id: Makefile,v 1.12 1996/09/19 16:19:40 peter Exp $
+
+SUBDIR= libdialog libg++ libgmp libmp libobjc libregex libreadline libstdc++
+
+.include <bsd.subdir.mk>
diff --git a/gnu/lib/Makefile.inc b/gnu/lib/Makefile.inc
new file mode 100644
index 0000000..605c0cd
--- /dev/null
+++ b/gnu/lib/Makefile.inc
@@ -0,0 +1,8 @@
+# $Id: Makefile.inc,v 1.3 1994/05/28 09:56:30 csgr Exp $
+
+SHLIB_MAJOR?= 2
+SHLIB_MINOR?= 0
+
+
+# NB: SHLIB major and minor nos. must also be specified in libg++/Makefile.inc
+# (This is due to the deeper tree structure of libg++)
diff --git a/gnu/lib/libdialog/CHANGES b/gnu/lib/libdialog/CHANGES
new file mode 100644
index 0000000..1467a0e
--- /dev/null
+++ b/gnu/lib/libdialog/CHANGES
@@ -0,0 +1,9 @@
+- Added two variables to call to dialog_menu() to save the position
+ in the menu when choosing a menu-option.
+
+- Added dialog_fselect(), implements a fileselector dialog
+- Added ui-interface objects: Stringobject, Listobject and Buttonobject.
+ The fileselector dialog was built using these objects.
+- changed dialog_menu to use PGUP and PGDN
+- Added dialog_mesgbox, which display text given in a char buffer.
+-
diff --git a/gnu/lib/libdialog/COPYING b/gnu/lib/libdialog/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/lib/libdialog/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <signature of Ty Coon>, 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/gnu/lib/libdialog/Makefile b/gnu/lib/libdialog/Makefile
new file mode 100644
index 0000000..599332e
--- /dev/null
+++ b/gnu/lib/libdialog/Makefile
@@ -0,0 +1,37 @@
+# Makefile for libdialog
+# $Id: Makefile,v 1.18 1996/08/13 12:46:10 jkh Exp $
+
+LIB= dialog
+MAN3= dialog.3
+
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 0
+SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \
+ lineedit.c radiolist.c textbox.c yesno.c prgbox.c raw_popen.c \
+ fselect.c ui_objects.c dir.c notify.c help.c gauge.c
+
+CFLAGS+= -I${.CURDIR} -Wall -Wstrict-prototypes -DLOCALE
+
+LDADD+= -lncurses -lmytinfo
+DPADD+= ${LIBNCURSES} ${LIBMYTINFO}
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/dialog.h \
+ ${DESTDIR}/usr/include
+
+MLINKS+=dialog.3 draw_shadow.3 dialog.3 draw_box.3 \
+ dialog.3 line_edit.3 dialog.3 strheight.3 \
+ dialog.3 strwidth.3 dialog.3 dialog_create_rc.3 \
+ dialog.3 dialog_yesno.3 dialog.3 dialog_prgbox.3 \
+ dialog.3 dialog_textbox.3 dialog.3 dialog_menu.3 \
+ dialog.3 dialog_checklist.3 dialog.3 dialog_radiolist.3 \
+ dialog.3 dialog_inputbox.3 dialog.3 dialog_clear_norefresh.3 \
+ dialog.3 dialog_clear.3 dialog.3 dialog_update.3 \
+ dialog.3 dialog_fselect.3 dialog.3 dialog_notify.3 \
+ dialog.3 dialog_mesgbox.3 dialog.3 dialog_gauge.3 \
+ dialog.3 init_dialog.3 dialog.3 end_dialog.3 \
+ dialog.3 use_helpfile.3 dialog.3 use_helpline.3 \
+ dialog.3 get_helpline.3 dialog.3 restore_helpline.3 \
+ dialog.3 dialog_msgbox.3
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libdialog/README b/gnu/lib/libdialog/README
new file mode 100644
index 0000000..e5e6d56
--- /dev/null
+++ b/gnu/lib/libdialog/README
@@ -0,0 +1,8 @@
+This library was split out from the `dialog' program for use
+in C programs. For a list of interface functions, see dialog.h.
+For usage examples, see the `dialog' program sources in
+/usr/src/gnu/usr.bin/dialog.
+
+You can additionally use any ncurses functions after init_dialog().
+
+ Ache.
diff --git a/gnu/lib/libdialog/TESTS/Makefile b/gnu/lib/libdialog/TESTS/Makefile
new file mode 100644
index 0000000..98ec3d2
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/Makefile
@@ -0,0 +1,67 @@
+# Really quick and evil Makefile for building all the tests. I wish that bmake was friendlier to
+# the concept of multiple progs/libs in the same directory.
+# $Id: Makefile,v 1.2 1996/01/01 03:45:21 jkh Exp $
+
+PROGS= msg yesno prgbox gauge dselect fselect text menu1 menu2 menu3 \
+ input1 check1 check2 check3 radio1 radio2 radio3
+
+CFLAGS+= -Wall -Wstrict-prototypes
+LDFLAGS += -ldialog -lncurses -lmytinfo
+
+all: ${PROGS}
+
+clean:
+ rm -f ${PROGS}
+
+msg: ${.CURDIR}/msg.c
+ ${CC} ${.CURDIR}/msg.c -o msg ${LDFLAGS}
+
+yesno: ${.CURDIR}/yesno.c
+ ${CC} ${.CURDIR}/yesno.c -o yesno ${LDFLAGS}
+
+prgbox: ${.CURDIR}/prgbox.c
+ ${CC} ${.CURDIR}/prgbox.c -o prgbox ${LDFLAGS}
+
+gauge: ${.CURDIR}/gauge.c
+ ${CC} ${.CURDIR}/gauge.c -o gauge ${LDFLAGS}
+
+dselect: ${.CURDIR}/dselect.c
+ ${CC} ${.CURDIR}/dselect.c -o dselect ${LDFLAGS}
+
+fselect: ${.CURDIR}/fselect.c
+ ${CC} ${.CURDIR}/fselect.c -o fselect ${LDFLAGS}
+
+text: ${.CURDIR}/text.c
+ ${CC} ${.CURDIR}/text.c -o text ${LDFLAGS}
+
+menu1: ${.CURDIR}/menu1.c
+ ${CC} ${.CURDIR}/menu1.c -o menu1 ${LDFLAGS}
+
+menu2: ${.CURDIR}/menu2.c
+ ${CC} ${.CURDIR}/menu2.c -o menu2 ${LDFLAGS}
+
+menu3: ${.CURDIR}/menu3.c
+ ${CC} ${.CURDIR}/menu3.c -o menu3 ${LDFLAGS}
+
+input1: ${.CURDIR}/input1.c
+ ${CC} ${.CURDIR}/input1.c -o input1 ${LDFLAGS}
+
+check1: ${.CURDIR}/check1.c
+ ${CC} ${.CURDIR}/check1.c -o check1 ${LDFLAGS}
+
+check2: ${.CURDIR}/check2.c
+ ${CC} ${.CURDIR}/check2.c -o check2 ${LDFLAGS}
+
+check3: ${.CURDIR}/check3.c
+ ${CC} ${.CURDIR}/check3.c -o check3 ${LDFLAGS}
+
+radio1: ${.CURDIR}/radio1.c
+ ${CC} ${.CURDIR}/radio1.c -o radio1 ${LDFLAGS}
+
+radio2: ${.CURDIR}/radio2.c
+ ${CC} ${.CURDIR}/radio2.c -o radio2 ${LDFLAGS}
+
+radio3: ${.CURDIR}/radio3.c
+ ${CC} ${.CURDIR}/radio3.c -o radio3 ${LDFLAGS}
+
+.include <bsd.prog.mk>
diff --git a/gnu/lib/libdialog/TESTS/check1.c b/gnu/lib/libdialog/TESTS/check1.c
new file mode 100644
index 0000000..e8a0751
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/check1.c
@@ -0,0 +1,82 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: check1.c,v 1.2 1996/04/07 03:20:50 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+
+static int
+clearBooks(dialogMenuItem *self)
+{
+ german_book = italian_book = slang_book = FALSE;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu2 - A more advanced way of using checked and fire hooks to manipulate the backing-variables directly */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu2[] = {
+ { "German", "Buy book on learning German", getBool, setBool, NULL, &german_book},
+ { "Italian", "Buy book on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy book on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_checklist("this is a dialog_checklist() in action, test #1",
+ "this checklist menu shows off some of the straight-forward features\n"
+ "of the new menu system's check & fire dispatch hooks", -1, -1, 4, -4, menu2, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_checklist was %d (%d %d %d)\n", retval, german_book, italian_book, slang_book);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/check2.c b/gnu/lib/libdialog/TESTS/check2.c
new file mode 100644
index 0000000..edad6cf
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/check2.c
@@ -0,0 +1,104 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: check2.c,v 1.1 1996/01/01 03:45:23 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+
+static int
+clearBooks(dialogMenuItem *self)
+{
+ german_book = italian_book = slang_book = FALSE;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
+buyBooks(dialogMenuItem *self)
+{
+ char foo[256];
+
+ if (german_book || italian_book || slang_book) {
+ strcpy(foo, "Ok, you're buying books on");
+ if (german_book)
+ strcat(foo, " german");
+ if (italian_book)
+ strcat(foo, " italian");
+ if (slang_book)
+ strcat(foo, " slang");
+ }
+ else
+ strcpy(foo, "You're not buying any books?");
+ dialog_mesgbox("This is a direct callback for the `Buy' button", foo, -1, -1);
+ return DITEM_SUCCESS;
+}
+
+/* menu3 - Look mom! We can finally use our own OK and Cancel buttons! */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu3[] = {
+ { "Buy!", NULL, NULL, buyBooks }, /* New "OK" button */
+ { "No Way!", NULL, NULL, NULL }, /* New "Cancel" button */
+ { "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
+ { "Italian", "Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "Clear", "Clear book list", NULL, clearBooks, NULL, NULL, ' ', ' ', ' ' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_checklist("this is dialog_checklist() in action, test #2",
+ "Same as before, but now we relabel the buttons and override the OK action.",
+ -1, -1, 4, -4, menu3 + 2, (char *)TRUE);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_checklist was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/check3.c b/gnu/lib/libdialog/TESTS/check3.c
new file mode 100644
index 0000000..6ba01ce
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/check3.c
@@ -0,0 +1,91 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: check3.c,v 1.1 1996/01/01 03:45:23 jkh Exp $
+ *
+ */
+
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+getBool(dialogMenuItem *self)
+{
+ if (self->data && *((int *)self->data))
+ return TRUE;
+ return FALSE;
+}
+
+static int
+setBool(dialogMenuItem *self)
+{
+ if (self->data) {
+ *((int *)self->data) = !*((int *)self->data);
+ return DITEM_SUCCESS;
+ }
+ return DITEM_FAILURE;
+}
+
+static int german_book, italian_book, slang_book;
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu4 - Show off a simulated compound menu (group at top is checklist, group at bottom radio) */
+/* prompt title checked fire sel, data lbra mark rbra */
+static dialogMenuItem menu4[] = {
+ { "German", "Buy books on learning German", getBool, setBool, NULL, &german_book },
+ { "Italian","Buy books on learning Italian", getBool, setBool, NULL, &italian_book },
+ { "Slang", "Buy books on commonly used insults", getBool, setBool, NULL, &slang_book },
+ { "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
+ { "1000", "Spend $1,000", check, spend, NULL, (void *)1000, '(', '*', ')' },
+ { "500", "Spend $500", check, spend, NULL, (void *)500, '(', '*', ')' },
+ { "100", "Spend $100", check, spend, NULL, (void *)100, '(', '*', ')' },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+
+ retval = dialog_checklist("this is dialog_checklist() in action, test #3",
+ "Now we show off some of the button 'styles' one can create.",
+ -1, -1, 7, -7, menu4, NULL);
+ dialog_clear();
+ fprintf(stderr, "spent $%d on %s%s%s books\n", spending, german_book ? " german" : "",
+ italian_book ? " italian" : "", slang_book ? " slang" : "");
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/dselect.c b/gnu/lib/libdialog/TESTS/dselect.c
new file mode 100644
index 0000000..8b673f6
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/dselect.c
@@ -0,0 +1,40 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_dselect(".", "*");
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_dselect was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/fselect.c b/gnu/lib/libdialog/TESTS/fselect.c
new file mode 100644
index 0000000..d07d726
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/fselect.c
@@ -0,0 +1,43 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ char *retval;
+
+ init_dialog();
+
+ retval = dialog_fselect(".", "*.[ch]");
+ dialog_clear();
+ if (retval)
+ fprintf(stderr, "returned value for dialog_fselect was %s\n", retval);
+ else
+ fprintf(stderr, "returned value for dialog_fselect was NULL\n");
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/gauge.c b/gnu/lib/libdialog/TESTS/gauge.c
new file mode 100644
index 0000000..b41209d
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/gauge.c
@@ -0,0 +1,40 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: gauge.c,v 1.1 1996/01/01 03:45:25 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int i;
+
+ init_dialog();
+
+ for (i = 0; i <= 100; i++) {
+ dialog_gauge("Gas tank", "When this gets 100% full, you'd better yank out the nozzle!", 10, 1, 7, 70, i);
+ usleep(30000);
+ }
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/input1.c b/gnu/lib/libdialog/TESTS/input1.c
new file mode 100644
index 0000000..edb45f5
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/input1.c
@@ -0,0 +1,44 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+ unsigned char result[128];
+
+ init_dialog();
+
+ strcpy(result, "not this!");
+ retval = dialog_inputbox("this is dialog_inputbox() in action, test #1",
+ "Enter something really profound below, please.",
+ -1, -1, result);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_inputbox was %d (%s)\n", retval, result);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/menu1.c b/gnu/lib/libdialog/TESTS/menu1.c
new file mode 100644
index 0000000..a06eade
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/menu1.c
@@ -0,0 +1,95 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: menu1.c,v 1.3 1996/04/16 12:17:22 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Start of hook functions */
+static enum { nowhere, berlin, rome, ny } where;
+
+static int
+_menu1_berlin_action(dialogMenuItem *self)
+{
+ if (where == berlin) {
+ dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
+ }
+ else {
+ where = berlin;
+ dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_rome_action(dialogMenuItem *self)
+{
+ if (where == rome) {
+ dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
+ }
+ else {
+ where = rome;
+ dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_ny_action(dialogMenuItem *self)
+{
+ if (where == ny) {
+ dialog_mesgbox("Say what?", "You're already there!", -1, -1);
+ }
+ else {
+ where = ny;
+ dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* menu1 - show off the "fire" action hook */
+/* prompt title checked fire */
+static dialogMenuItem menu1[] = {
+ { "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
+ { "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
+ { "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_menu("this is dialog_menu() in action, test #1",
+ "this simple menu shows off some of the straight-forward features\n"
+ "of the new menu system's action dispatch hooks. Select Cancel to leave",
+ -1, -1, 3, -3, menu1, NULL, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/menu2.c b/gnu/lib/libdialog/TESTS/menu2.c
new file mode 100644
index 0000000..c1602f7
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/menu2.c
@@ -0,0 +1,95 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: menu2.c,v 1.3 1996/04/16 12:17:23 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Start of hook functions */
+static enum { nowhere, berlin, rome, ny } where;
+
+static int
+_menu1_berlin_action(dialogMenuItem *self)
+{
+ if (where == berlin)
+ dialog_mesgbox("excuse me?", "But you're already *in* Berlin!", -1, -1);
+ else {
+ where = berlin;
+ dialog_mesgbox("whoosh!", "Welcome to Berlin! Have a beer!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_rome_action(dialogMenuItem *self)
+{
+ if (where == rome)
+ dialog_mesgbox("The wine must be getting to you..", "You're already in Rome!", -1, -1);
+ else {
+ where = rome;
+ dialog_mesgbox("whoosh!", "Welcome to Rome! Have a coffee!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+static int
+_menu1_ny_action(dialogMenuItem *self)
+{
+ if (where == ny)
+ dialog_mesgbox("Say what?", "You're already there!", -1, -1);
+ else {
+ where = ny;
+ dialog_mesgbox("whoosh!", "Welcome to New York! Now go someplace else!", -1, -1);
+ }
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* menu1 - show off the "fire" action hook */
+/* prompt title checked fire */
+static dialogMenuItem menu1[] = {
+ { "Berlin", "Go visit Germany's new capitol", NULL, _menu1_berlin_action },
+ { "Rome", "Go visit the Roman ruins", NULL, _menu1_rome_action },
+ { "New York", "Go visit the streets of New York", NULL, _menu1_ny_action },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ use_helpfile("menu2.c");
+ use_helpline("Type F1 to view the source for this demo");
+ retval = dialog_menu("this is dialog_menu() in action, test #2",
+ "this simple menu shows off some of the straight-forward features\n"
+ "of the new menu system's action dispatch hooks as well as a helpline\n"
+ "and a helpfile. Select Cancel to leave",
+ -1, -1, 3, -3, menu1, NULL, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/menu3.c b/gnu/lib/libdialog/TESTS/menu3.c
new file mode 100644
index 0000000..c91db64
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/menu3.c
@@ -0,0 +1,106 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: menu3.c,v 1.4 1996/04/18 13:21:26 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int
+stop(dialogMenuItem *self)
+{
+ dialog_mesgbox("!", "I'm no idiot!", -1, -1);
+ return DITEM_SUCCESS;
+}
+
+static int
+maybe(dialogMenuItem *self)
+{
+ dialog_mesgbox("!", "I said don't rush me! I'm THINKING!", -1, -1);
+ return DITEM_SUCCESS | DITEM_RESTORE | DITEM_CONTINUE;
+}
+
+/* Dummy menu just to show of the ability */
+static char *insurance[] = {
+ "1,000,000", "Mondo insurance policy", "Off",
+ "5,000,000", "Mega insurance policy", "Off",
+ "10,000,000", "Friend! Most Favored customer!"
+};
+
+static void
+preinsure(dialogMenuItem *self, int is_selected)
+{
+ if (is_selected) {
+ static WINDOW *w;
+
+ /* This has to be here first if you want to see selection traverse properly in the invoking menu */
+ refresh();
+
+ w = dupwin(newscr);
+ DialogX = 1;
+ DialogY = 13;
+ dialog_radiolist("How much insurance would you like to take out?",
+ "If you're really going to do this, we recommend some insurance\n"
+ "first! What kind of life insurance policy would you like?",
+ -1, -1, 3, 3, insurance, NULL);
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+ }
+}
+
+/*
+ * Show a simple menu that puts up a sub menu when a certain item is traversed to
+ */
+
+/* prompt title checked fire sel */
+static dialogMenuItem doit[] = {
+ { "Rah!" },
+ { "No way!" },
+ { "Stop", "No, I'm not going to do that!", NULL, stop, NULL },
+ { "Maybe", "I'm still thinking about it, don't rush me!", NULL, maybe, NULL, },
+ { "Go", "Yes! Yes! I want to do it!", NULL, NULL, preinsure },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+
+ DialogX = 5;
+ DialogY = 1;
+ retval = dialog_menu("Do you have the GUTS?",
+ "C'mon, macho man! Do you have what it takes to do something REALLY\n"
+ "dangerous and stupid? WHAT ARE YOU WAITING FOR?!",
+ -1, -1, 3, -3, doit + 2, (char *)TRUE, NULL, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_menu was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/msg.c b/gnu/lib/libdialog/TESTS/msg.c
new file mode 100644
index 0000000..9c2edc4
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/msg.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_msgbox("This is dialog_msgbox() in action with pause on", "Hi there. Please press return now.",
+ -1, -1, 1);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_msgbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/prgbox.c b/gnu/lib/libdialog/TESTS/prgbox.c
new file mode 100644
index 0000000..6a751c3
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/prgbox.c
@@ -0,0 +1,40 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_prgbox("This is dialog_prgbox() in action with cal(1)", "cal", 14, 50, TRUE, TRUE);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_prgbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/radio1.c b/gnu/lib/libdialog/TESTS/radio1.c
new file mode 100644
index 0000000..1953207
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/radio1.c
@@ -0,0 +1,70 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: radio1.c,v 1.2 1996/04/07 03:20:57 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu5 - Show a simple radiolist menu that inherits the radio appearance by default */
+/* prompt title checked fire sel data */
+static dialogMenuItem menu5[] = {
+ { "1000", "Spend $1,000", check, spend, NULL, (void *)1000 },
+ { "500", "Spend $500", check, spend, NULL, (void *)500 },
+ { "100", "Spend $100", check, spend, NULL, (void *)100 },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #1",
+ "this radio menu shows off some of the straight-forward features\n"
+ "of the new menu system's check & fire dispatch hooks", -1, -1, 3, -3, menu5, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/radio2.c b/gnu/lib/libdialog/TESTS/radio2.c
new file mode 100644
index 0000000..3f97048
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/radio2.c
@@ -0,0 +1,88 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: radio2.c,v 1.2 1996/04/07 03:20:59 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static char bachelor[10], bachelette[10];
+
+static int
+getBachelor(dialogMenuItem *self)
+{
+ return !strcmp(bachelor, self->prompt);
+}
+
+static int
+setBachelor(dialogMenuItem *self)
+{
+ strcpy(bachelor, self->prompt);
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static int
+getBachelette(dialogMenuItem *self)
+{
+ return !strcmp(bachelette, self->prompt);
+}
+
+static int
+setBachelette(dialogMenuItem *self)
+{
+ strcpy(bachelette, self->prompt);
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+/* menu6- More complex radiolist menu that creates two groups in a single menu */
+/* prompt title checked fire */
+static dialogMenuItem menu6[] = {
+ { "Tom", "Tom's a dynamic shoe salesman from Tulsa, OK!", getBachelor, setBachelor },
+ { "Dick", "Dick's a retired engine inspector from McDonnell-Douglas!", getBachelor, setBachelor },
+ { "Harry", "Harry's a professional female impersonator from Las Vegas!", getBachelor, setBachelor },
+ { "-----", "----------------------------------", NULL, NULL, NULL, NULL, ' ', ' ', ' ' },
+ { "Jane", "Jane's a twice-divorced housewife from Moose, Oregon!", getBachelette, setBachelette },
+ { "Sally", "Sally's a shy Human Resources Manager for IBM!", getBachelette, setBachelette },
+ { "Mary", "Mary's an energetic serial killer on the lam!", getBachelette, setBachelette },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #2",
+ "Welcome to \"The Love Blender!\" - America's favorite game show\n"
+ "where YOU, the contestant, get to choose which of these two\n"
+ "fine specimens of humanity will go home together, whether they\n"
+ "like it or not!", -1, -1, 7, -7, menu6, NULL);
+ dialog_clear();
+ fprintf(stderr, "I'm sure that %s and %s will be very happy together!\n", bachelor, bachelette);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/radio3.c b/gnu/lib/libdialog/TESTS/radio3.c
new file mode 100644
index 0000000..6a50287
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/radio3.c
@@ -0,0 +1,97 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: radio3.c,v 1.2 1996/04/07 03:21:01 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Hook functions */
+
+static int spending;
+
+static int
+check(dialogMenuItem *self)
+{
+ return ((int)self->data == spending);
+}
+
+static int
+spend(dialogMenuItem *self)
+{
+ spending = (int)self->data;
+ return DITEM_SUCCESS | DITEM_REDRAW;
+}
+
+static void
+ask(dialogMenuItem *self, int is_selected)
+{
+ if (is_selected) {
+ char *str;
+
+ if (!strcmp(self->prompt, "1000"))
+ str = "You'd better ask both your parents first! ";
+ else if (!strcmp(self->prompt, "500"))
+ str = "You'd better at least ask your Dad! ";
+ else
+ str = "Yes, being frugal is probably a good idea!";
+ DialogX = 15;
+ DialogY = 17;
+ dialog_msgbox("Free Advice", str, -1, -1, 0);
+ }
+}
+
+/*
+ * menu5 - Show a simple radiolist menu that inherits the radio appearance by default and appears at
+ * a different location, leaving room for a msg box below it. This shows off the DialogX/DialogY extensions.
+ */
+
+/* prompt title checked fire sel data */
+static dialogMenuItem menu5[] = {
+ { "1000", "Spend $1,000", check, spend, ask, (void *)1000 },
+ { "500", "Spend $500", check, spend, ask, (void *)500 },
+ { "100", "Spend $100", check, spend, ask, (void *)100 },
+};
+
+/* End of hook functions */
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+
+ DialogX = 5;
+ DialogY = 1;
+ retval = dialog_radiolist("this is dialog_radiolist() in action, test #3",
+ "This radio menu shows off the ability to put dialog menus and other\n"
+ "controls at different locations, as well as the `selected' hook which\n"
+ "lets you follow the traversal of the selection bar as well as what's\n"
+ "selected.",
+ -1, -1, 3, -3, menu5, NULL);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_radiolist was %d (money set to %d)\n", retval, spending);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/text.c b/gnu/lib/libdialog/TESTS/text.c
new file mode 100644
index 0000000..f63b533
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/text.c
@@ -0,0 +1,40 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_textbox("This is dialog_textbox() in action with /etc/passwd", "/etc/passwd", 10, 60);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_textbox was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TESTS/yesno.c b/gnu/lib/libdialog/TESTS/yesno.c
new file mode 100644
index 0000000..841451a
--- /dev/null
+++ b/gnu/lib/libdialog/TESTS/yesno.c
@@ -0,0 +1,41 @@
+/*
+ * small test-driver for new dialog functionality
+ *
+ * Copyright (c) 1995, Jordan Hubbard
+ *
+ * All rights reserved.
+ *
+ * This source code may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of the software nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ * $Id: test1.c,v 1.2 1995/12/23 14:53:07 jkh Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <dialog.h>
+
+/* Kick it off, James! */
+int
+main(int argc, unsigned char *argv[])
+{
+ int retval;
+
+ init_dialog();
+
+ retval = dialog_yesno("This is dialog_yesno() in action",
+ "Have you stopped deliberately putting bugs into your code?", -1, -1);
+ dialog_clear();
+ fprintf(stderr, "returned value for dialog_yesno was %d\n", retval);
+
+ end_dialog();
+ return 0;
+}
diff --git a/gnu/lib/libdialog/TODO b/gnu/lib/libdialog/TODO
new file mode 100644
index 0000000..132a4a4
--- /dev/null
+++ b/gnu/lib/libdialog/TODO
@@ -0,0 +1,36 @@
+- cut off names in the listbox that are to long
+done 27Jan95
+ The current behaviour may not be desirable. When browsing through
+ long names these, when highlighted, will be shown with the first
+ characters cut off, when not highlighted the last characters will
+ be cut off.
+
+- look at behaviour of TAB key when browsing through directories.
+done 28Jan95
+
+- make sure the full name of the directory is written to the
+ "Directory:"-box
+done 28Jan95
+
+- mark current selections in listbox when initializing the listobject
+Idontknow
+- test and use Notify() when checking for error conditions
+ok
+- test overall
+- adapt color of buttons when changing focus to the button.
+done 28Jan95
+- add shade to dialog_fselect()-window
+done 29Jan95
+- add (nn%) indication to lists.
+done 30Jan95
+- add use_helpfile()
+done 13Feb95
+- add use_helpline()
+
+NOTE: apparently there is a bug (or a strange interaction between pkg_manage
+and dialog_textbox) in dialog_textbox. When I use this routine to display
+the helpfile in display_helpfile() the program gets mysterious segmentation
+faults and bus errors.
+I now use dialog_mesgbox, after I have read the file into a buffer.
+
+
diff --git a/gnu/lib/libdialog/checklist.c b/gnu/lib/libdialog/checklist.c
new file mode 100644
index 0000000..98a2a81
--- /dev/null
+++ b/gnu/lib/libdialog/checklist.c
@@ -0,0 +1,539 @@
+/*
+ * checklist.c -- implements the checklist box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected,
+ dialogMenuItem *me);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+static int list_width, check_x, item_x;
+
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int
+dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width,
+ int list_height, int cnt, void *it, unsigned char *result)
+{
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice, item_no = 0, *status;
+ int redraw_menu = FALSE;
+ char okButton, cancelButton;
+ WINDOW *dialog, *list;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
+ exit(-1);
+ }
+
+draw:
+ /* Previous calling syntax, e.g. just a list of strings? */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ /* Initializes status */
+ for (i = 0; i < item_no; i++)
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ items[i*3] = ditems[i].prompt;
+ items[i*3 + 1] = ditems[i].title;
+ items[i*3 + 2] = status[i] ? "on" : "off";
+ }
+ }
+ max_choice = MIN(list_height, item_no);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center checklist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+list_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j);
+ width = MAX(width,check_x+4)+4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
+ return -1;
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
+
+ list_width = width - 6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - list_width) / 2 - 1;
+
+ /* create new window for the list */
+ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
+ if (list == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
+ y + box_y + 1, x + box_x + 1);
+ return -1;
+ }
+ keypad(list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
+
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + item_x + 6;
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-11;
+ y = height-2;
+ /* Is this a fancy new style argument string where we get to override
+ * the buttons, or an old style one where they're fixed?
+ */
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* Shortcut to OK? */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ strcat(result, "\n");
+ }
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return 0;
+ }
+ /* Shortcut to cancel? */
+ else if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ wmove(dialog, cur_y, cur_x);
+ }
+ delwin(save);
+ }
+ delwin(list);
+ delwin(dialog);
+ return 1;
+ }
+
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || key == KEY_UP ||
+ key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
+
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+ /* Scroll list down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll+choice < item_no-1) {
+ /* Scroll list up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
+ status[scroll+max_choice-1], max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
+ scrollok(list, TRUE);
+ scroll(list);
+ scrollok(list, FALSE);
+ }
+ scroll++;
+ print_item(list, items[(scroll+max_choice-1)*3], items[(scroll+max_choice-1)*3 + 1],
+ status[scroll+max_choice-1], max_choice-1, TRUE, DREF(ditems, scroll + max_choice - 1));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if (key == ' ') { /* Toggle item status */
+ char lbra = 0, rbra = 0, mark = 0;
+
+ if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ if (st & DITEM_REDRAW) {
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ for (i = 0; i < max_choice; i++) {
+ print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
+ status[scroll + i], i, i == choice, DREF(ditems, scroll + i));
+ }
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4,
+ cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ delwin(save);
+ if (st & DITEM_LEAVE_MENU) {
+ /* Allow a fire action to take us out of the menu */
+ key = ESC;
+ break;
+ }
+ else if (st & DITEM_RECREATE) {
+ delwin(list);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ status[scroll + choice] = ditems[scroll + choice].checked ?
+ ditems[scroll + choice].checked(&ditems[scroll + choice]) : FALSE;
+ lbra = ditems[scroll + choice].lbra;
+ rbra = ditems[scroll + choice].rbra;
+ mark = ditems[scroll + choice].mark;
+ }
+ else
+ status[scroll + choice] = !status[scroll + choice];
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ wmove(list, choice, check_x);
+ wattrset(list, check_selected_attr);
+ if (!lbra)
+ lbra = '[';
+ if (!rbra)
+ rbra = ']';
+ if (!mark)
+ mark = 'X';
+ wprintw(list, "%c%c%c", lbra, status[scroll+choice] ? mark : ' ', rbra);
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ continue; /* wait for another key press */
+ }
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, FALSE,
+ DREF(ditems, scroll + choice));
+
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll+choice)*3], items[(scroll+choice)*3 + 1], status[scroll+choice], choice, TRUE,
+ DREF(ditems, scroll + choice));
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_PPAGE: /* can we go up? */
+ if (scroll > height - 4)
+ scroll -= (height-4);
+ else
+ scroll = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_NPAGE: /* can we go down a full page? */
+ if (scroll + list_height >= item_no-1 - list_height) {
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ }
+ else
+ scroll += list_height;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_HOME: /* go to the top */
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_END: /* Go to the bottom */
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ break;
+
+ /* swap the selection of OK/Cancel buttons */
+ case TAB:
+ case KEY_BTAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wrefresh(dialog);
+ break;
+
+ /* Select either the OK or Cancel button */
+ case '\n':
+ case '\r':
+ if (ditems) {
+ if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
+ int st;
+ WINDOW *save = dupwin(newscr);
+
+ st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (st == DITEM_FAILURE)
+ continue;
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ strcat(result, "\n");
+ }
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return button;
+ break;
+
+ /* Let me outta here! */
+ case ESC:
+ break;
+
+ /* Help! */
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ if (redraw_menu) {
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll+i)*3], items[(scroll+i)*3 + 1], status[scroll+i], i, i == choice,
+ DREF(ditems, scroll + i));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ redraw_menu = FALSE;
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_checklist() */
+
+
+/*
+ * Print list item
+ */
+static void
+print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int status, int choice, int selected,
+ dialogMenuItem *me)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, check_x);
+ wattrset(win, selected ? check_selected_attr : check_attr);
+ wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '[',
+ status ? me && me->mark ? me->mark : 'X' : ' ',
+ me && me->rbra ? me->rbra : ']');
+ wattrset(win, menubox_attr);
+ waddch(win, ' ');
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libdialog/colors.h b/gnu/lib/libdialog/colors.h
new file mode 100644
index 0000000..7cea0a0
--- /dev/null
+++ b/gnu/lib/libdialog/colors.h
@@ -0,0 +1,219 @@
+/*
+ * colors.h -- color attribute definitions
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+/*
+ * Default color definitions
+ *
+ * *_FG = foreground
+ * *_BG = background
+ * *_HL = highlight?
+ */
+#define SCREEN_FG COLOR_CYAN
+#define SCREEN_BG COLOR_BLUE
+#define SCREEN_HL TRUE
+
+#define SHADOW_FG COLOR_BLACK
+#define SHADOW_BG COLOR_BLACK
+#define SHADOW_HL TRUE
+
+#define DIALOG_FG COLOR_BLACK
+#define DIALOG_BG COLOR_WHITE
+#define DIALOG_HL FALSE
+
+#define TITLE_FG COLOR_YELLOW
+#define TITLE_BG COLOR_WHITE
+#define TITLE_HL TRUE
+
+#define BORDER_FG COLOR_WHITE
+#define BORDER_BG COLOR_WHITE
+#define BORDER_HL TRUE
+
+#define BUTTON_ACTIVE_FG COLOR_WHITE
+#define BUTTON_ACTIVE_BG COLOR_BLUE
+#define BUTTON_ACTIVE_HL TRUE
+
+#define BUTTON_INACTIVE_FG COLOR_BLACK
+#define BUTTON_INACTIVE_BG COLOR_WHITE
+#define BUTTON_INACTIVE_HL FALSE
+
+#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE
+#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE
+#define BUTTON_KEY_ACTIVE_HL TRUE
+
+#define BUTTON_KEY_INACTIVE_FG COLOR_RED
+#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE
+#define BUTTON_KEY_INACTIVE_HL FALSE
+
+#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW
+#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE
+#define BUTTON_LABEL_ACTIVE_HL TRUE
+
+#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK
+#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE
+#define BUTTON_LABEL_INACTIVE_HL TRUE
+
+#define INPUTBOX_FG COLOR_BLACK
+#define INPUTBOX_BG COLOR_WHITE
+#define INPUTBOX_HL FALSE
+
+#define INPUTBOX_BORDER_FG COLOR_BLACK
+#define INPUTBOX_BORDER_BG COLOR_WHITE
+#define INPUTBOX_BORDER_HL FALSE
+
+#define SEARCHBOX_FG COLOR_BLACK
+#define SEARCHBOX_BG COLOR_WHITE
+#define SEARCHBOX_HL FALSE
+
+#define SEARCHBOX_TITLE_FG COLOR_YELLOW
+#define SEARCHBOX_TITLE_BG COLOR_WHITE
+#define SEARCHBOX_TITLE_HL TRUE
+
+#define SEARCHBOX_BORDER_FG COLOR_WHITE
+#define SEARCHBOX_BORDER_BG COLOR_WHITE
+#define SEARCHBOX_BORDER_HL TRUE
+
+#define POSITION_INDICATOR_FG COLOR_YELLOW
+#define POSITION_INDICATOR_BG COLOR_WHITE
+#define POSITION_INDICATOR_HL TRUE
+
+#define MENUBOX_FG COLOR_BLACK
+#define MENUBOX_BG COLOR_WHITE
+#define MENUBOX_HL FALSE
+
+#define MENUBOX_BORDER_FG COLOR_WHITE
+#define MENUBOX_BORDER_BG COLOR_WHITE
+#define MENUBOX_BORDER_HL TRUE
+
+#define ITEM_FG COLOR_BLACK
+#define ITEM_BG COLOR_WHITE
+#define ITEM_HL FALSE
+
+#define ITEM_SELECTED_FG COLOR_WHITE
+#define ITEM_SELECTED_BG COLOR_BLUE
+#define ITEM_SELECTED_HL TRUE
+
+#define TAG_FG COLOR_YELLOW
+#define TAG_BG COLOR_WHITE
+#define TAG_HL TRUE
+
+#define TAG_SELECTED_FG COLOR_YELLOW
+#define TAG_SELECTED_BG COLOR_BLUE
+#define TAG_SELECTED_HL TRUE
+
+#define TAG_KEY_FG COLOR_RED
+#define TAG_KEY_BG COLOR_WHITE
+#define TAG_KEY_HL TRUE
+
+#define TAG_KEY_SELECTED_FG COLOR_RED
+#define TAG_KEY_SELECTED_BG COLOR_BLUE
+#define TAG_KEY_SELECTED_HL TRUE
+
+#define CHECK_FG COLOR_BLACK
+#define CHECK_BG COLOR_WHITE
+#define CHECK_HL FALSE
+
+#define CHECK_SELECTED_FG COLOR_WHITE
+#define CHECK_SELECTED_BG COLOR_BLUE
+#define CHECK_SELECTED_HL TRUE
+
+#define UARROW_FG COLOR_GREEN
+#define UARROW_BG COLOR_WHITE
+#define UARROW_HL TRUE
+
+#define DARROW_FG COLOR_GREEN
+#define DARROW_BG COLOR_WHITE
+#define DARROW_HL TRUE
+
+/* End of default color definitions */
+
+#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
+#define COLOR_NAME_LEN 10
+#define COLOR_COUNT 8
+
+
+/*
+ * Global variables
+ */
+
+typedef struct {
+ unsigned char name[COLOR_NAME_LEN];
+ int value;
+} color_names_st;
+
+
+#ifdef __DIALOG_MAIN__
+
+/*
+ * For matching color names with color values
+ */
+color_names_st color_names[] = {
+ {"BLACK", COLOR_BLACK},
+ {"RED", COLOR_RED},
+ {"GREEN", COLOR_GREEN},
+ {"YELLOW", COLOR_YELLOW},
+ {"BLUE", COLOR_BLUE},
+ {"MAGENTA", COLOR_MAGENTA},
+ {"CYAN", COLOR_CYAN},
+ {"WHITE", COLOR_WHITE},
+}; /* color names */
+
+
+/*
+ * Table of color values
+ */
+int color_table[][3] = {
+ {SCREEN_FG, SCREEN_BG, SCREEN_HL },
+ {SHADOW_FG, SHADOW_BG, SHADOW_HL },
+ {DIALOG_FG, DIALOG_BG, DIALOG_HL },
+ {TITLE_FG, TITLE_BG, TITLE_HL },
+ {BORDER_FG, BORDER_BG, BORDER_HL },
+ {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL },
+ {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL },
+ {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL },
+ {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL },
+ {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL },
+ {BUTTON_LABEL_INACTIVE_FG,BUTTON_LABEL_INACTIVE_BG,BUTTON_LABEL_INACTIVE_HL},
+ {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL },
+ {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL },
+ {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL },
+ {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL },
+ {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL },
+ {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL },
+ {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL },
+ {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL },
+ {ITEM_FG, ITEM_BG, ITEM_HL },
+ {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL },
+ {TAG_FG, TAG_BG, TAG_HL },
+ {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL },
+ {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL },
+ {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL },
+ {CHECK_FG, CHECK_BG, CHECK_HL },
+ {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL },
+ {UARROW_FG, UARROW_BG, UARROW_HL },
+ {DARROW_FG, DARROW_BG, DARROW_HL },
+}; /* color_table */
+
+#else
+
+extern color_names_st color_names[];
+extern int color_table[][3];
+
+#endif /* __DIALOG_MAIN__ */
diff --git a/gnu/lib/libdialog/dialog.3 b/gnu/lib/libdialog/dialog.3
new file mode 100644
index 0000000..7d9b690
--- /dev/null
+++ b/gnu/lib/libdialog/dialog.3
@@ -0,0 +1,391 @@
+.\"
+.\" Copyright (c) 1995, Jordan Hubbard
+.\"
+.\" All rights reserved.
+.\"
+.\" This manual page may be used, modified, copied, distributed, and
+.\" sold, in both source and binary form provided that the above
+.\" copyright and these terms are retained, verbatim, as the first
+.\" lines of this file. Under no circumstances is the author
+.\" responsible for the proper functioning of the software described herein
+.\" nor does the author assume any responsibility for damages incurred with
+.\" its use.
+.\"
+.\" $Id: dialog.3,v 1.2 1996/01/01 03:43:51 jkh Exp $
+.\"
+.Dd December 18, 1995
+.Dt dialog 3
+.Os FreeBSD 2
+.Sh NAME
+.Nm draw_shadow ,
+.Nm draw_box ,
+.Nm line_edit ,
+.Nm strheight ,
+.Nm strwidth ,
+.Nm dialog_create_rc,
+.Nm dialog_yesno ,
+.Nm dialog_prgbox ,
+.Nm dialog_msgbox ,
+.Nm dialog_textbox ,
+.Nm dialog_menu ,
+.Nm dialog_checklist ,
+.Nm dialog_radiolist ,
+.Nm dialog_inputbox ,
+.Nm dialog_clear_norefresh ,
+.Nm dialog_clear ,
+.Nm dialog_update ,
+.Nm dialog_fselect ,
+.Nm dialog_notify ,
+.Nm dialog_mesgbox ,
+.Nm dialog_gauge ,
+.Nm init_dialog ,
+.Nm end_dialog ,
+.Nm use_helpfile ,
+.Nm use_helpline ,
+.Nm get_helpline ,
+.Nm restore_helpline
+.Nd Provide a simple ncurses-based "GUI" interface.
+.Sh DESCRIPTION
+The dialog library attempts to provide a fairly simplistic set of
+fixed-presentation menus, input boxes, gauges, file requestors and
+other general purpose "GUI" (a bit of a stretch, since it uses
+ncurses) objects. Since the library also had its roots in a
+shell-script writer's utility (see the \fBdialog(1)\fR command), the
+early API was somewhat primitively based on strings being passed in or
+out and parsed. This API was later extended to take either the
+original arguments or arrays of \fBdialogMenuItem\fR structures,
+giving the user much more control over the internal behavior of each
+control. The \fBdialogMenuItem\fR structure internals are public:
+
+.nf
+typedef struct _dmenu_item {
+ char *\fBprompt\fR;
+ char *\fBtitle\fR;
+ int (*\fBchecked\fR)(struct _dmenu_item *self);
+ int (*\fBfire\fR)(struct _dmenu_item *self);
+ int (*\fBselected\fR)(struct _dmenu_item *self, int is_selected);
+ void *\fBdata\fR;
+ char \fBlbra\fR, \fBmark\fR, \fBrbra\fR;
+} \fBdialogMenuItem\fR;
+.fi
+
+The \fBprompt\fR and \fBtitle\fR strings are pretty much self-explanatory,
+and the \fBchecked\fR and \fBfire\fR function pointers provide optional
+display and action hooks (the \fBdata\fR variable being available for
+the convenience of those hooks) when more tightly coupled feedback between
+a menu object and user code is required. The \fBselected\fR hook also
+allows you to verify whether or not a given item is selected (the cursor is
+over it) for implementing pretty much any possible context-sensitive
+behavior. A number of clever tricks for simulating various kinds of item
+types can also be done by adjusting the values of \fBlbra\fR
+(default: '['), \fB\mark\fR (default: '*' for radio menus, 'X' for check menus)
+and \fBrbra\fR (default: ']') and declaring a reasonable \fBchecked\fR hook,
+which should return TRUE for the `marked' state and FALSE for `unmarked.'
+If an item has a \fBfire\fR hook associated with it, it will also be called
+whenever the item is "toggled" in some way and should return one of the
+following codes:
+.nf
+
+#define DITEM_SUCCESS 0 /* Successful completion */
+#define DITEM_FAILURE -1 /* Failed to "fire" */
+#define DITEM_LEAVE_MENU -2 /* Treat selection as "Ok" */
+#define DITEM_REDRAW -3 /* Menu has changed, redraw it */
+
+Two special globals also exist for putting a dialog at any arbitrary
+X,Y location (the early designers rather short-sightedly made no provisions
+for this). If set to zero, the default centering behavior will be in
+effect.
+
+.fi
+
+.Sh SYNOPSIS
+.Fd #include <dialog.h>
+.Ft "void"
+.Fn draw_shadow "WINDOW *win" "int y" "int x" "int height" "int width"
+
+Draws a shadow in curses window \fBwin\fR using the dimensions
+of \fBx, y, width\fR and \fBheight\fR. Returns 0 on success, -1 on failure.
+
+.Ft "void"
+.Fn draw_box "WINDOW *win" "int y" "int x" "int height" "int width" "chtype box" "chtype border"
+
+Draws a bordered box using the dimensions of \fBx, y, width\fR and
+\fBheight\fR. The attributes from \fBbox\fR and \fBborder\fR are
+used, if specified, while painting the box and border regions of the
+object.
+
+.Ft "int"
+.Fn line_edit "WINDOW *dialog" "int box_y" "int box_x" "int flen" "int box_width" "chtype attrs" "int first" "u_char *result"
+
+Invoke a simple line editor with an edit box of dimensions \fBbox_x,
+box_y\fR and \fBbox_width\fR. The field length is constrained by
+\fBflen\fR, starting at the \fBfirst\fR character specified and
+optionally displayed with character attributes \fBattrs\fR. The
+string being edited is stored in \fBresult\fR.
+
+Returns 0 on success, -1 on failure.
+
+.Ft "int"
+.Fn strheight "const char *p"
+
+Returns the height of string in \fBp\fR, counting newlines.
+
+.Ft "int"
+.Fn strwidth "const char *p"
+
+Returns the width of string in \fBp\fR, counting newlines.
+
+.Ft "void"
+.Fn dialog_create_rc "u_char *filename"
+
+Dump dialog library settings into \fBfilename\fR for later retreival
+as defaults. Returns 0 on success, -1 on failure.
+
+.Ft "int"
+.Fn dialog_yesno "u_char *title" "u_char *prompt" "int height" "int width"
+
+Display a text box using \fBtitle\fR and \fBprompt\fR strings of dimensions
+\fBheight\fR and \fBwidth\fR. Also paint a pair of \fBYes\fR and \fBNo\fR
+buttons at the bottom. If the \fBYes\fR button is chosen, return FALSE.
+If \fBNo\fR, return TRUE.
+
+.Ft "int"
+.Fn dialog_prgbox "u_char *title" "u_char *line" "int height" "int width" "int pause" "int use_shell"
+
+Display a text box of dimensions \fBheight\fR and \fBwidth\fR
+containing the output of command \fBline\fR. If \fBuse_shell\fR is
+TRUE, \fBline\fR is passed as an argument to \fBsh(1)\fR, otherwise it
+is simply passed to \fBexec(3)\fR. If \fBpause\fR is TRUE, a final
+confirmation requestor will be put up when execution terminates.
+
+Returns 0 on success, -1 on failure.
+
+.Ft "int"
+.Fn dialog_textbox "u_char *title" "u_char *prompt" "int height" "int width"
+
+Display a text box containing the contents of string \fBprompt\fR of dimensions
+\fBheight\fR and \fBwidth\fR.
+
+Returns 0 on success, -1 on failure.
+
+.Ft "int"
+.Fn dialog_menu "u_char *title" "u_char *prompt" "int height" "int width" "int menu_height" "int item_no" "void *itptr" "u_char *result, int *ch, int *sc"
+
+Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
+optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
+and \fBitptr\fR arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use. To use the
+older and traditional interface, \fBitem_no\fR should be a positive
+integer representing the number of string pointer pairs to find in
+\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
+expected to be in prompt and title order for each item and the
+\fBresult\fR parameter is expected to point to an array where the
+prompt string of the item selected will be copied. To use the newer
+interface, \fBitem_no\fR should be a \fInegative\fR integer
+representing the number of \fBdialogMenuItem\fR structures pointed to
+by \fBitptr\fR (which should be of type \fBdialogMenuItem *\fR), one
+structure per item. In the new interface, the \fBresult\fR variable
+is used as a simple boolean (not a pointer) and should be NULL if
+\fBitptr\fR only points to menu items and the default \fBOK\fR and
+\fBCancel\fR buttons are desired. If \fBresult\fR is non-NULL, then
+\fBitptr\fR is actually expected to point 2 locations \fBpast\fR the
+start of the menu item list. \fBitptr\fR[-1] is then expected to
+point to an item representing the \fBCancel\fR button, from which the
+\fBprompt\fR and \fBfire\fR actions are used to override the default
+behavior, and \fBitptr\fR[-2] to the same for the \fBOK\fR button.
+
+Using either API behavior, the \fBch\fR and \fBsc\fR values may be passed in to preserve current
+item selection and scroll position values across calls.
+
+Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
+
+.Ft "int"
+.Fn dialog_checklist "u_char *title" "u_char *prompt" "int height" "int width" "int m_height" "int item_no" "void *itptr" "u_char *result"
+
+Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
+optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
+and \fBitptr\fR arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use. To use the
+older and traditional interface, \fBitem_no\fR should be a positive
+integer representing the number of string pointer tuples to find in
+\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
+expected to be in prompt, title and state ("on" or "off") order for
+each item and the \fBresult\fR parameter is expected to point to an
+array where the prompt string of the item(s) selected will be
+copied. To use the newer interface, \fBitem_no\fR should be a
+\fInegative\fR integer representing the number of \fBdialogMenuItem\fR
+structures pointed to by \fBitptr\fR (which should be of type
+\fBdialogMenuItem *\fR), one structure per item. In the new interface,
+the \fBresult\fR variable is used as a simple boolean (not a pointer)
+and should be NULL if \fBitptr\fR only points to menu items and the
+default \fBOK\fR and \fBCancel\fR buttons are desired. If
+\fBresult\fR is non-NULL, then \fBitptr\fR is actually expected to
+point 2 locations \fBpast\fR the start of the menu item list.
+\fBitptr\fR[-1] is then expected to point to an item representing the
+\fBCancel\fR button, from which the \fBprompt\fR and \fBfire\fR
+actions are used to override the default behavior, and \fBitptr\fR[-2]
+to the same for the \fBOK\fR button.
+
+In the standard API model, the menu supports the selection of multiple items,
+each of which is marked with an `X' character to denote selection. When
+the OK button is selected, the prompt values for all items selected are
+concatenated into the \fBresult\fR string.
+
+In the new API model, it is not actually necessary to preserve
+"checklist" semantics at all since practically everything about how
+each item is displayed or marked as "selected" is fully configurable.
+You could have a single checklist menu that actually contained a group
+of items with "radio" behavior, "checklist" behavior and standard menu
+item behavior. The only reason to call \fBdialog_checklist\fR over
+\fBdialog_radiolist\fR in the new API model is to inherit the base
+behavior, you're no longer constrained by it.
+
+Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
+
+.Ft "int"
+.Fn dialog_radiolist "u_char *title" "u_char *prompt" "int height" "int width" "int m_height" "int item_no" "void *it" "u_char *result"
+
+Display a menu of dimensions \fBheight\fR and \fBwidth\fR with an
+optional internal menu height of \fBmenu_height\fR. The \fBitem_no\fR
+and \fBitptr\fR arguments are of particular importance since they,
+together, determine which of the 2 available APIs to use. To use the
+older and traditional interface, \fBitem_no\fR should be a positive
+integer representing the number of string pointer tuples to find in
+\fBitptr\fR (which should be of type \fBchar **\fR), the strings are
+expected to be in prompt, title and state ("on" or "off") order for
+each item and the \fBresult\fR parameter is expected to point to an
+array where the prompt string of the item(s) selected will be
+copied. To use the newer interface, \fBitem_no\fR should be a
+\fInegative\fR integer representing the number of \fBdialogMenuItem\fR
+structures pointed to by \fBitptr\fR (which should be of type
+\fBdialogMenuItem *\fR), one structure per item. In the new interface,
+the \fBresult\fR variable is used as a simple boolean (not a pointer)
+and should be NULL if \fBitptr\fR only points to menu items and the
+default \fBOK\fR and \fBCancel\fR buttons are desired. If
+\fBresult\fR is non-NULL, then \fBitptr\fR is actually expected to
+point 2 locations \fBpast\fR the start of the menu item list.
+\fBitptr\fR[-1] is then expected to point to an item representing the
+\fBCancel\fR button, from which the \fBprompt\fR and \fBfire\fR
+actions are used to override the default behavior, and \fBitptr\fR[-2]
+does the same for the traditional \fBOK\fR button.
+
+In the standard API model, the menu supports the selection of only one
+of multiple items, the currently active item marked with an `*'
+character to denote selection. When the OK button is selected, the
+prompt value for this item is copied into the \fBresult\fR string.
+
+In the new API model, it is not actually necessary to preserve
+"radio button" semantics at all since practically everything about how
+each item is displayed or marked as "selected" is fully configurable.
+You could have a single radio menu that actually contained a group
+of items with "checklist" behavior, "radio" behavior and standard menu
+item behavior. The only reason to call \fBdialog_radiolist\fR over
+\fBdialog_checklistlist\fR in the new API model is to inherit the base
+behavior.
+
+Returns 0 on success, 1 on Cancel and -1 on failure or ESC.
+
+.Ft "int"
+.Fn dialog_inputbox "u_char *title" "u_char *prompt" "int height" "int width" "u_char *result"
+
+Displays a single-line text input field in a box displaying \fBtitle\fR and \fBprompt\fR
+of dimensions \fBheight\fR and \fBwidth\fR. The field entered is stored in \fBresult\fR.
+
+Returns 0 on success, -1 on failure or ESC.
+
+.Ft "char *"
+.Fn dialog_fselect "char *dir" "char *fmask"
+
+Brings up a file selector dialog starting at \fBdir\fR and showing only those file names
+matching \fBfmask\fR.
+
+Returns filename selected or NULL.
+
+.Ft "int"
+.Fn dialog_dselect "char *dir" "char *fmask"
+
+Brings up a directory selector dialog starting at \fBdir\fR and showing only those directory names
+matching \fBfmask\fR.
+
+Returns directory name selected or NULL.
+
+.Ft "void"
+.Fn dialog_notify "char *msg"
+
+Bring up a generic "hey, you!" notifier dialog containing \fBmsg\fR.
+
+.Ft "int"
+.Fn dialog_mesgbox "u_char *title" "u_char *prompt" "int height" "int width"
+
+Like a notifier dialog, but with more control over \fBtitle\fR, \fBprompt\fR, \fBwidth\fR and
+\fBheight\fR. This object will also wait for user confirmation, unlike \fBdialog_notify\fR.
+
+Returns 0 on success, -1 on failure.
+
+.Ft "void"
+.Fn dialog_gauge "u_char *title" "u_char *prompt" "int y" "int x" "int height" "int width" "int perc"
+
+Display a horizontal bar-graph style gauge. A value of \fB100\fR for \fBperc\fR constitutes
+a full gauge, a value of \fB0\fR an empty one.
+
+.Ft "void"
+.Fn use_helpfile "char *helpfile"
+
+For any menu supporting context sensitive help, invoke the text box
+object on this file whenever the \fBF1\fR key is pressed.
+
+
+.Ft "void"
+.Fn use_helpline "char *helpline"
+
+Display this line of helpful text below any menu being displayed.
+
+.Ft "char *"
+.Fn get_helpline "void"
+
+Get the current value of the helpful text line.
+
+.Ft "void"
+.Fn dialog_clear_norefresh "void"
+
+Clear the screen back to the dialog background color, but don't refresh the contents
+just yet.
+
+.Ft "void"
+.Fn dialog_clear "void"
+
+Clear the screen back to the dialog background color immediately.
+
+.Ft "void"
+.Fn dialog_update "void"
+
+Do any pending screen refreshes now.
+
+.Ft "void"
+.Fn init_dialog "void"
+
+Initialize the dialog library (call this routine before any other dialog API calls).
+
+.Ft "void"
+.Fn end_dialog "void"
+
+Shut down the dialog library (call this if you need to get back to sanity).
+
+.Sh SEE ALSO
+.Xr dialog 1 ,
+.Xr ncurses 3
+
+.Sh AUTHORS
+The primary author would appear to be Savio Lam <lam836@cs.cuhk.hk> with contributions over
+the years by Stuart Herbert <S.Herbert@sheffield.ac.uk>, Marc van Kempen <wmbfmk@urc.tue.nl>,
+Andrey Chernov <ache@freebsd.org> and Jordan Hubbard <jkh@freebsd.org>.
+
+.Sh HISTORY
+These functions appeared in
+.Em FreeBSD-2.0
+as the \fBdialog(1)\fR command and were soon split into library
+and command by Andrey Chernov. Marc van Kempen implemented most of the
+extra controls and objects and Jordan Hubbard added the dialogMenuItem
+renovations and this man page.
+.Sh BUGS
+Sure!
diff --git a/gnu/lib/libdialog/dialog.h b/gnu/lib/libdialog/dialog.h
new file mode 100644
index 0000000..37f05af
--- /dev/null
+++ b/gnu/lib/libdialog/dialog.h
@@ -0,0 +1,158 @@
+#ifndef _DIALOG_H_INCLUDE
+#define _DIALOG_H_INCLUDE
+
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define HAVE_NCURSES
+
+#ifdef HAVE_NCURSES
+#include <ncurses.h>
+
+#else
+
+#ifdef ultrix
+#include <cursesX.h>
+#else
+#include <curses.h>
+#endif
+
+#endif
+
+/* special return codes for `fire' actions */
+#define DITEM_STATUS(flag) ((flag) & 0x0000FFFF)
+#define DITEM_SUCCESS 0
+#define DITEM_FAILURE 1
+
+/* Flags - returned in upper 16 bits of return status */
+#define DITEM_LEAVE_MENU (1 << 16)
+#define DITEM_REDRAW (1 << 17)
+#define DITEM_RECREATE (1 << 18)
+#define DITEM_RESTORE (1 << 19)
+#define DITEM_CONTINUE (1 << 20)
+
+
+/* negative offsets for buttons in item lists, if specified */
+#define OK_BUTTON -2
+#define CANCEL_BUTTON -1
+
+/* for use in describing more exotic behaviors */
+typedef struct _dmenu_item {
+ char *prompt;
+ char *title;
+ int (*checked)(struct _dmenu_item *self);
+ int (*fire)(struct _dmenu_item *self);
+ void (*selected)(struct _dmenu_item *self, int is_selected);
+ void *data;
+ char lbra, mark, rbra;
+ int aux;
+} dialogMenuItem;
+
+#define VERSION "0.4"
+#define MAX_LEN 2048
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+extern int DialogX, DialogY;
+
+/*
+ * Attribute names
+ */
+#define screen_attr attributes[0]
+#define shadow_attr attributes[1]
+#define dialog_attr attributes[2]
+#define title_attr attributes[3]
+#define border_attr attributes[4]
+#define button_active_attr attributes[5]
+#define button_inactive_attr attributes[6]
+#define button_key_active_attr attributes[7]
+#define button_key_inactive_attr attributes[8]
+#define button_label_active_attr attributes[9]
+#define button_label_inactive_attr attributes[10]
+#define inputbox_attr attributes[11]
+#define inputbox_border_attr attributes[12]
+#define searchbox_attr attributes[13]
+#define searchbox_title_attr attributes[14]
+#define searchbox_border_attr attributes[15]
+#define position_indicator_attr attributes[16]
+#define menubox_attr attributes[17]
+#define menubox_border_attr attributes[18]
+#define item_attr attributes[19]
+#define item_selected_attr attributes[20]
+#define tag_attr attributes[21]
+#define tag_selected_attr attributes[22]
+#define tag_key_attr attributes[23]
+#define tag_key_selected_attr attributes[24]
+#define check_attr attributes[25]
+#define check_selected_attr attributes[26]
+#define uarrow_attr attributes[27]
+#define darrow_attr attributes[28]
+
+/* number of attributes */
+#define ATTRIBUTE_COUNT 29
+
+extern chtype attributes[];
+
+#ifdef HAVE_NCURSES
+extern bool use_shadow;
+void draw_shadow(WINDOW *win, int y, int x, int height, int width);
+#endif
+void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border);
+int line_edit(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, chtype attrs, int first, unsigned char *result);
+int strheight(const char *p);
+int strwidth(const char *p);
+
+void dialog_create_rc(unsigned char *filename);
+int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int width);
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell);
+int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause);
+int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width);
+int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height,
+ int item_no, void *itptr, unsigned char *result, int *ch, int *sc);
+int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int item_no, void *itptr, unsigned char *result);
+int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int item_no, void *itptr, unsigned char *result);
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result);
+void dialog_clear_norefresh(void);
+void dialog_clear(void);
+void dialog_update(void);
+void init_dialog(void);
+void end_dialog(void);
+
+/* Additions to libdialog */
+char *dialog_fselect(char *dir, char *fmask);
+int dialog_dselect(char *dir, char *fmask);
+void dialog_notify(char *msg);
+int dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width);
+void use_helpfile(char *helpfile);
+void use_helpline(char *helpline);
+char *get_helpline(void);
+void restore_helpline(char *helpline);
+void dialog_gauge(char *title, char *prompt, int y, int x, int height, int width, int perc);
+
+#endif /* _DIALOG_H_INCLUDE */
diff --git a/gnu/lib/libdialog/dialog.priv.h b/gnu/lib/libdialog/dialog.priv.h
new file mode 100644
index 0000000..9d32f65
--- /dev/null
+++ b/gnu/lib/libdialog/dialog.priv.h
@@ -0,0 +1,178 @@
+/*
+ * dialog.h -- common declarations for all dialog modules
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(LOCALE)
+#include <locale.h>
+#endif
+
+
+/*
+ * Change these if you want
+ */
+#define USE_SHADOW TRUE
+#define USE_COLORS TRUE
+
+#define ESC 27
+#define TAB 9
+#define BUF_SIZE (10*1024)
+
+#ifndef MIN
+#define MIN(x,y) (x < y ? x : y)
+#endif
+#ifndef MAX
+#define MAX(x,y) (x > y ? x : y)
+#endif
+
+#ifndef ctrl
+#define ctrl(a) ((a) - 'a' + 1)
+#endif
+
+#ifndef HAVE_NCURSES
+#ifndef ACS_ULCORNER
+#define ACS_ULCORNER '+'
+#endif
+#ifndef ACS_LLCORNER
+#define ACS_LLCORNER '+'
+#endif
+#ifndef ACS_URCORNER
+#define ACS_URCORNER '+'
+#endif
+#ifndef ACS_LRCORNER
+#define ACS_LRCORNER '+'
+#endif
+#ifndef ACS_HLINE
+#define ACS_HLINE '-'
+#endif
+#ifndef ACS_VLINE
+#define ACS_VLINE '|'
+#endif
+#ifndef ACS_LTEE
+#define ACS_LTEE '+'
+#endif
+#ifndef ACS_RTEE
+#define ACS_RTEE '+'
+#endif
+#ifndef ACS_UARROW
+#define ACS_UARROW '^'
+#endif
+#ifndef ACS_DARROW
+#define ACS_DARROW 'v'
+#endif
+#endif /* HAVE_NCURSES */
+
+/*
+ * Global variables
+ */
+#ifdef __DIALOG_MAIN__
+
+#ifdef HAVE_NCURSES
+
+/* use colors by default? */
+bool use_colors = USE_COLORS;
+
+/* shadow dialog boxes by default?
+ Note that 'use_shadow' implies 'use_colors' */
+bool use_shadow = USE_SHADOW;
+
+#endif
+
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] = {
+ A_NORMAL, /* screen_attr */
+ A_NORMAL, /* shadow_attr */
+ A_REVERSE, /* dialog_attr */
+ A_REVERSE, /* title_attr */
+ A_REVERSE, /* border_attr */
+ A_BOLD, /* button_active_attr */
+ A_DIM, /* button_inactive_attr */
+ A_UNDERLINE, /* button_key_active_attr */
+ A_UNDERLINE, /* button_key_inactive_attr */
+ A_NORMAL, /* button_label_active_attr */
+ A_NORMAL, /* button_label_inactive_attr */
+ A_REVERSE, /* inputbox_attr */
+ A_REVERSE, /* inputbox_border_attr */
+ A_REVERSE, /* searchbox_attr */
+ A_REVERSE, /* searchbox_title_attr */
+ A_REVERSE, /* searchbox_border_attr */
+ A_REVERSE, /* position_indicator_attr */
+ A_REVERSE, /* menubox_attr */
+ A_REVERSE, /* menubox_border_attr */
+ A_REVERSE, /* item_attr */
+ A_NORMAL, /* item_selected_attr */
+ A_REVERSE, /* tag_attr */
+ A_REVERSE, /* tag_selected_attr */
+ A_NORMAL, /* tag_key_attr */
+ A_BOLD, /* tag_key_selected_attr */
+ A_REVERSE, /* check_attr */
+ A_REVERSE, /* check_selected_attr */
+ A_REVERSE, /* uarrow_attr */
+ A_REVERSE /* darrow_attr */
+};
+
+#else
+
+#ifdef HAVE_NCURSES
+extern bool use_colors;
+#endif
+
+#endif /* __DIALOG_MAIN__ */
+
+
+
+#ifdef HAVE_NCURSES
+
+/*
+ * Function prototypes
+ */
+#ifdef __DIALOG_MAIN__
+
+extern int parse_rc(void);
+
+#endif /* __DIALOG_MAIN__ */
+
+#endif
+
+
+#ifdef HAVE_NCURSES
+void color_setup(void);
+#endif
+
+void attr_clear(WINDOW *win, int height, int width, chtype attr);
+void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth,
+ int y, int x, int center, int rawmode);
+void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected);
+FILE *raw_popen(const char *program, char * const *argv, const char *type);
+int raw_pclose(FILE *iop);
+void display_helpfile(void);
+void display_helpline(WINDOW *w, int y, int width);
+void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no, int box_x,
+ int box_y, int tag_x, int cur_x, int cur_y);
+
diff --git a/gnu/lib/libdialog/dir.c b/gnu/lib/libdialog/dir.c
new file mode 100644
index 0000000..9c2c7b5
--- /dev/null
+++ b/gnu/lib/libdialog/dir.c
@@ -0,0 +1,549 @@
+/****************************************************************************
+ *
+ * Program: dir.c
+ * Author: Marc van Kempen
+ * desc: Directory routines, sorting and reading
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <unistd.h> /* XXX for _POSIX_VERSION ifdefs */
+
+#if !defined sgi && !defined _POSIX_VERSION
+#include <sys/dir.h>
+#endif
+#if defined __sun__
+#include <sys/dirent.h>
+#endif
+#if defined sgi || defined _POSIX_VERSION
+#include <dirent.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <fnmatch.h>
+#include <sys/param.h>
+#include "dir.h"
+
+/****************************************************************************
+ *
+ * local prototypes
+ *
+ ****************************************************************************/
+
+void toggle_dotfiles(void);
+int show_dotfiles(void);
+int dir_alphasort(const void *d1, const void *d2);
+int dir_sizesort(const void *d1, const void *d2);
+int dir_datesort(const void *d1, const void *d2);
+int dir_extsort(const void *d1, const void *d2);
+
+/****************************************************************************
+ *
+ * global variables
+ *
+ ****************************************************************************/
+
+
+/* This is user-selectable, I've set them fixed for now however */
+
+void *_sort_func = dir_alphasort;
+static int _showdotfiles = TRUE;
+
+/****************************************************************************
+ *
+ * Functions
+ *
+ ****************************************************************************/
+
+int
+dir_select_nd(
+#if defined __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and other dot-files
+ * keep '..' however.
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".")==0 ||
+ (d->d_name[0] == '.' && strlen(d->d_name) > 1 && d->d_name[1] != '.')) {
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+}/* dir_select_nd() */
+
+
+int
+dir_select(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".")==0) { /* don't include the current directory */
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+} /* dir_select() */
+
+int
+dir_select_root_nd(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and the parent directory.
+ * Also skip any other dot-files.
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name[0] != "." else FALSE
+ */
+{
+ if (d->d_name[0] == '.') { /* don't include the current directory */
+ return(FALSE); /* nor the parent directory */
+ } else {
+ return(TRUE);
+ }
+} /* dir_select_root_nd() */
+
+
+int
+dir_select_root(
+#ifdef __linux__
+ const struct dirent *d
+#else
+ struct dirent *d
+#endif
+)
+/*
+ * desc: allways include a directory entry <d>, except
+ * for the current directory and the parent directory
+ * pre: <d> points to a dirent
+ * post: returns TRUE if d->d_name[0] != "." else FALSE
+ */
+{
+ if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
+ return(FALSE);
+ } else {
+ return(TRUE);
+ }
+}/* dir_select_root() */
+
+
+#ifdef NO_ALPHA_SORT
+int
+alphasort(const void *d1, const void *d2)
+/*
+ * desc: a replacement for what should be in the library
+ */
+{
+ return(strcmp(((struct dirent *) d1)->d_name,
+ ((struct dirent *) d2)->d_name));
+} /* alphasort() */
+#endif
+
+int
+dir_alphasort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2, but put directories always first
+ * put '..' always on top
+ *
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(strcmp(f1->filename, f2->filename));
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(strcmp(f1->filename, f2->filename));
+
+} /* dir_alphasort() */
+
+
+int
+dir_sizesort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2, but put directories always first
+ *
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(s1->st_size < s2->st_size ?
+ -1
+ :
+ s1->st_size >= s2->st_size);
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(s1->st_size < s2->st_size ?
+ -1
+ :
+ s1->st_size >= s2->st_size);
+
+} /* dir_sizesort() */
+
+int
+dir_datesort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2 on date, but put directories always first
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+ /* put directories first */
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ return(s1->st_mtime < s2->st_mtime ?
+ -1
+ :
+ s1->st_mtime >= s2->st_mtime);
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ return(s1->st_mtime < s2->st_mtime ?
+ -1
+ :
+ s1->st_mtime >= s2->st_mtime);
+
+} /* dir_datesort() */
+
+
+int
+null_strcmp(char *s1, char *s2)
+/*
+ * desc: compare strings allowing NULL pointers
+ */
+{
+ if ((s1 == NULL) && (s2 == NULL)) {
+ return(0);
+ }
+ if (s1 == NULL) {
+ return(-1);
+ }
+ if (s2 == NULL) {
+ return(1);
+ }
+ return(strcmp(s1, s2));
+} /* null_strcmp() */
+
+
+int
+dir_extsort(const void *d1, const void *d2)
+/*
+ * desc: compare d1 and d2 on extension, but put directories always first
+ * extension = "the characters after the last dot in the filename"
+ * pre: d1 and d2 are pointers to DirList type records
+ * post: see code
+ */
+{
+ DirList *f1 = ((DirList *) d1),
+ *f2 = ((DirList *) d2);
+ struct stat *s1 = &(f1->filestatus);
+ struct stat *s2 = &(f2->filestatus);
+ char *ext1, *ext2;
+ int extf, ret;
+
+
+ /* check for '..' */
+ if (strcmp(((DirList *) d1)->filename, "..") == 0) {
+ return(-1);
+ }
+ if (strcmp(((DirList *) d2)->filename, "..") == 0) {
+ return(1);
+ }
+
+
+ /* find the first extension */
+
+ ext1 = f1->filename + strlen(f1->filename);
+ extf = FALSE;
+ while (!extf && (ext1 > f1->filename)) {
+ extf = (*--ext1 == '.');
+ }
+ if (!extf) {
+ ext1 = NULL;
+ } else {
+ ext1++;
+ }
+ /* ext1 == NULL if there's no "extension" else ext1 points */
+ /* to the first character of the extension string */
+
+ /* find the second extension */
+
+ ext2 = f2->filename + strlen(f2->filename);
+ extf = FALSE;
+ while (!extf && (ext2 > f2->filename)) {
+ extf = (*--ext2 == '.');
+ }
+ if (!extf) {
+ ext2 = NULL;
+ } else {
+ ext2++;
+ }
+ /* idem as for ext1 */
+
+ if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) {
+ ret = null_strcmp(ext1, ext2);
+ if (ret == 0) {
+ return(strcmp(f1->filename, f2->filename));
+ } else {
+ return(ret);
+ }
+ };
+ if (s1->st_mode & S_IFDIR) {
+ return(-1);
+ }
+ if (s2->st_mode & S_IFDIR) {
+ return(1);
+ }
+ ret = null_strcmp(ext1, ext2);
+ if (ret == 0) {
+ return(strcmp(f1->filename, f2->filename));
+ } else {
+ return(ret);
+ }
+
+} /* dir_extsort() */
+
+
+void
+get_dir(char *dirname, char *fmask, DirList **dir, int *n)
+/*
+ * desc: get the files in the current directory
+ * pre: <dir> == NULL
+ * post: <dir> contains <n> dir-entries
+ */
+{
+ char cwd[MAXPATHLEN];
+ char buf[256];
+ struct dirent **dire;
+ struct stat status;
+ int i, j, nb;
+ long d;
+
+
+ getcwd(cwd, MAXPATHLEN);
+ if (strcmp(cwd, "/") == 0) { /* we are in the root directory */
+ if (show_dotfiles()) {
+ *n = scandir(dirname, &dire, dir_select_root, alphasort);
+ } else {
+ *n = scandir(dirname, &dire, dir_select_root_nd, alphasort);
+ }
+ } else {
+ if (show_dotfiles()) {
+ *n = scandir(dirname, &dire, dir_select, alphasort);
+ } else {
+ *n = scandir(dirname, &dire, dir_select_nd, alphasort);
+ }
+ }
+
+ /* There is the possibility that we have entered a directory */
+ /* which we are not allowed to read, scandir thus returning */
+ /* -1 for *n. */
+ /* Actually I should also check for lack of memory, but I'll */
+ /* let my application happily crash if this is the case */
+ /* Solution: */
+ /* manually insert the parent directory as the only */
+ /* directory entry, and return. */
+
+ if (*n == -1) {
+ *n = 1;
+ *dir = (DirList *) malloc(sizeof(DirList));
+ strcpy((*dir)[0].filename, "..");
+ lstat("..", &status);
+ (*dir)[0].filestatus = status;
+ (*dir)[0].link = FALSE;
+ return;
+ }
+
+ *dir = (DirList *) malloc( *n * sizeof(DirList) );
+ d = 0;
+ i = 0;
+ j = 0;
+ while (j<*n) {
+ lstat(dire[j]->d_name, &status);
+ /* check if this file is to be included */
+ /* always include directories, the rest is subject to fmask */
+ if (S_ISDIR(status.st_mode)
+ || fnmatch(fmask, dire[j]->d_name, FNM_NOESCAPE) != FNM_NOMATCH) {
+ strcpy((*dir)[i].filename, dire[j]->d_name);
+ (*dir)[i].filestatus = status;
+ if ((S_IFMT & status.st_mode) == S_IFLNK) { /* handle links */
+ (*dir)[i].link = TRUE;
+ stat(dire[j]->d_name, &status);
+ nb = readlink(dire[j]->d_name, buf, 256);
+ if (nb == -1) {
+ printf("get_dir(): Error reading link: %s\n", dire[j]->d_name);
+ exit(-1);
+ } else {
+ (*dir)[i].linkname = malloc(sizeof(char) * nb + 1);
+ strncpy((*dir)[i].linkname, buf, nb);
+ (*dir)[i].linkname[nb] = 0;
+ }
+ (*dir)[i].filestatus = status;
+ } else {
+ (*dir)[i].link = FALSE;
+ (*dir)[i].linkname = NULL;
+ }
+ i++;
+ } else {
+ /* skip this entry */
+ }
+ j++;
+ }
+ *n = i;
+
+ /* sort the directory with the directory names on top */
+ qsort((*dir), *n, sizeof(DirList), _sort_func);
+
+ /* Free the allocated memory */
+ for (i=0; i<*n; i++) {
+ free(dire[i]);
+ }
+ free(dire);
+
+ return;
+}/* get_dir() */
+
+
+void
+FreeDir(DirList *d, int n)
+/*
+ * desc: free the dirlist d
+ * pre: d != NULL
+ * post: memory allocated to d has been released
+ */
+{
+ int i;
+
+ if (d) {
+ for (i=0; i<n; i++) {
+ if (d[i].linkname) {
+ free(d[i].linkname);
+ }
+ }
+ free(d);
+ } else {
+ printf("dir.c:FreeDir(): d == NULL\n");
+ exit(-1);
+ }
+
+ return;
+} /* FreeDir() */
+
+void
+toggle_dotfiles(void)
+/*
+ * desc: toggle visibility of dot-files
+ */
+{
+ _showdotfiles = !_showdotfiles;
+
+ return;
+} /* toggle_dotfiles() */
+
+int
+show_dotfiles(void)
+/*
+ * desc: return the value of _showdotfiles
+ */
+{
+ return(_showdotfiles);
+} /* show_dotfiles() */
+
+void
+set_dotfiles(int b)
+/*
+ * desc: set the value of _showdotfiles
+ */
+{
+ _showdotfiles = b;
+
+ return;
+} /* set_dotfiles() */
diff --git a/gnu/lib/libdialog/dir.h b/gnu/lib/libdialog/dir.h
new file mode 100644
index 0000000..eadc0c5
--- /dev/null
+++ b/gnu/lib/libdialog/dir.h
@@ -0,0 +1,38 @@
+/*
+ * include file for dir.c
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/dirent.h>
+
+typedef struct DirList { /* structure to hold the directory entries */
+ char filename[MAXNAMLEN]; /* together with the stat-info per file */
+ struct stat filestatus; /* filename, or the name to which it points */
+ int link; /* is it a link ? */
+ char *linkname; /* the name of the file the link points to */
+} DirList;
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+void get_dir(char *dirname, char *fmask, DirList **dir, int *n);
+void get_filenames(DirList *d, int n, char ***names, int *nf);
+void FreeDir(DirList *d, int n);
diff --git a/gnu/lib/libdialog/fselect.c b/gnu/lib/libdialog/fselect.c
new file mode 100644
index 0000000..4a8d075
--- /dev/null
+++ b/gnu/lib/libdialog/fselect.c
@@ -0,0 +1,400 @@
+/*
+ * program: fselect.c
+ * author: Marc van Kempen (wmbfmk@urc.tue.nl)
+ * Desc: File selection routine
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <dialog.h>
+#include "ui_objects.h"
+#include "dir.h"
+#include "dialog.priv.h"
+
+/*
+ * Local prototypes
+ */
+
+char *dialog_dfselect(char *dir, char *fmask, int is_fselect);
+
+/*
+ * Functions
+ */
+
+void
+get_directories(DirList *d, int n, char ***names, int *nd)
+/*
+ * Desc: return the directorienames in <dir> as an array in
+ * <names>, the # of entries in <nd>, memory allocated
+ * to *names should be freed when done with it.
+ */
+{
+ int i;
+
+ /* count the directories, which are in front */
+ *nd = 0;
+ while ((*nd < n) && (S_ISDIR(d[*nd].filestatus.st_mode))) (*nd)++;
+ *names = (char **) malloc( *nd * sizeof(char *) );
+ for (i=0; i<*nd; i++) {
+ (*names)[i] = (char *) malloc( strlen(d[i].filename) + 1);
+ strcpy((*names)[i], d[i].filename);
+ }
+
+ return;
+} /* get_directories() */
+
+void
+get_filenames(DirList *d, int n, char ***names, int *nf)
+/*
+ * Desc: return the filenames in <dir> as an arry in
+ * <names>, the # of entries in <nf>, memory allocated
+ * to *names should be freed when done.
+ */
+{
+ int nd, i;
+
+ /* the # of regular files is the total # of files - # of directories */
+ /* count the # of directories */
+ nd = 0;
+ while ((nd < n) && (S_ISDIR(d[nd].filestatus.st_mode))) nd++;
+
+ *names = (char **) malloc( (n-nd) * sizeof(char *) );
+ *nf = n - nd;
+ for (i=0; i<*nf; i++) {
+ (*names)[i] = (char *) malloc( strlen(d[i+nd].filename) + 1);
+ strcpy((*names)[i], d[i+nd].filename);
+ }
+
+ return;
+} /* get_filenames() */
+
+void
+FreeNames(char **names, int n)
+/*
+ * Desc: free the space occupied by names
+ */
+{
+ int i;
+
+ /* free the space occupied by names */
+ for (i=0; i<n; i++) {
+ free(names[i]);
+ }
+ free(names);
+
+ return;
+} /* FreeNames() */
+
+int
+dialog_dselect_old(void)
+/*
+ * Desc: starting from the current directory,
+ * choose a new current directory
+ */
+{
+ DirList *d = NULL;
+ char **names, old_dir[MAXPATHLEN];
+ WINDOW *ds_win;
+ ButtonObj *okbut, *cancelbut;
+ ListObj *dirs_obj;
+ StringObj *dir_obj;
+ char o_dir[MAXPATHLEN];
+ struct ComposeObj *obj = NULL;
+ int n, nd, okbutton, cancelbutton,
+ quit, cancel, ret;
+
+ ds_win = newwin(LINES-8, COLS-30, 4, 15);
+ if (ds_win == NULL) {
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
+ LINES-8, COLS-30, 4, 15);
+ exit(1);
+ }
+ draw_box(ds_win, 0, 0, LINES-8, COLS-30, dialog_attr, border_attr);
+ wattrset(ds_win, dialog_attr);
+ mvwaddstr(ds_win, 0, (COLS-30)/2 - 9, " Directory Select ");
+ draw_shadow(stdscr, 4, 15, LINES-8, COLS-30);
+ display_helpline(ds_win, LINES-9, COLS-30);
+
+ /* the Directory string input field */
+ getcwd(o_dir, MAXPATHLEN);
+ dir_obj = NewStringObj(ds_win, "Directory:", o_dir, 1, 2, COLS-34, MAXPATHLEN-1);
+ AddObj(&obj, STRINGOBJ, (void *) dir_obj);
+
+ /* the list of directories */
+ get_dir(".", "*", &d, &n);
+ get_directories(d, n, &names, &nd);
+ dirs_obj = NewListObj(ds_win, "Directories:", names, o_dir, 5, 2,
+ LINES-15, COLS-48, nd);
+ AddObj(&obj, LISTOBJ, (void *) dirs_obj);
+
+ /* the Ok-button */
+ okbutton = FALSE;
+ okbut = NewButtonObj(ds_win, "Continue", &okbutton, 7, COLS-45);
+ AddObj(&obj, BUTTONOBJ, (void *) okbut);
+
+ /* the Cancel-button */
+ cancelbutton = FALSE;
+ cancelbut = NewButtonObj(ds_win, "Return", &cancelbutton, 11, COLS-44);
+ AddObj(&obj, BUTTONOBJ, (void *) cancelbut);
+
+ quit = FALSE;
+ cancel = FALSE;
+ strcpy(old_dir, o_dir);
+ while (!quit) {
+ ret = PollObj(&obj);
+ switch(ret) {
+ case SEL_BUTTON:
+ if (okbutton) {
+ quit = TRUE;
+ }
+ if (cancelbutton) {
+ quit = TRUE;
+ cancel = TRUE;
+ }
+ break;
+ case SEL_CR:
+ if (strcmp(old_dir, o_dir)) {
+ /* the directory was changed, cd into it */
+ if (chdir(o_dir)) {
+ dialog_notify("Could not change into directory");
+ } else {
+ getcwd(o_dir, MAXPATHLEN);
+ strcpy(old_dir, o_dir);
+ RefreshStringObj(dir_obj);
+ }
+ }
+ get_dir(".", "*", &d, &n);
+ FreeNames(names, nd);
+ get_directories(d, n, &names, &nd);
+ UpdateListObj(dirs_obj, names, nd);
+ if (((obj->prev)->obj == (void *) dirs_obj)) {
+ obj=obj->prev;
+ }
+ break;
+ case SEL_ESC:
+ quit = TRUE;
+ cancel = TRUE;
+ break;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ }
+ }
+
+ FreeNames(names, nd);
+ DelObj(obj);
+ delwin(ds_win);
+
+ return(cancel);
+
+} /* dialog_dselect() */
+
+int
+dialog_dselect(char *dir, char *fmask)
+/*
+ * Desc: Choose a directory
+ */
+{
+ if (dialog_dfselect(dir, fmask, FALSE)) {
+ return(FALSE); /* esc or cancel was pressed */
+ } else {
+ return(TRUE); /* directory was selected */
+ }
+} /* dialog_dselect() */
+
+char *
+dialog_fselect(char *dir, char *fmask)
+/*
+ * Desc: Choose a file from a directory
+ */
+{
+ return(dialog_dfselect(dir, fmask, TRUE));
+} /* dialog_fselect() */
+
+char *
+dialog_dfselect(char *dir, char *fmask, int is_fselect)
+/*
+ * Desc: choose a file from the directory <dir>, which
+ * initially display files with the mask <filemask>
+ * pre: <dir> is the initial directory
+ * only files corresponding to the mask <fmask> are displayed
+ * post: returns NULL if no file was selected
+ * else returns pointer to filename, space is allocated, should
+ * be freed after use.
+ */
+{
+ DirList *d = NULL;
+ char msg[512];
+ char **fnames, **dnames, *ret_name;
+ WINDOW *fs_win;
+ int n, nd, nf, ret;
+ StringObj *fm_obj, *dir_obj, *sel_obj;
+ char o_fm[255], o_dir[MAXPATHLEN], o_sel[MAXPATHLEN];
+ char old_fmask[255], old_dir[MAXPATHLEN];
+ ListObj *dirs_obj, *files_obj;
+ struct ComposeObj *obj = NULL, *o;
+ int quit, cancel;
+ ButtonObj *okbut_obj, *canbut_obj;
+ int ok_button, cancel_button;
+
+ if (chdir(dir)) {
+ sprintf(msg, "Could not move into specified directory: %s", dir);
+ dialog_notify(msg);
+ return(NULL);
+ }
+ getcwd(o_dir, MAXPATHLEN);
+
+ /* setup the fileselect-window and initialize its components */
+ fs_win = newwin(LINES-2, COLS-20, 1, 10);
+ if (fs_win == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n",
+ LINES-2, COLS-20, 2, 10);
+ exit(1);
+ }
+ draw_box(fs_win, 0, 0, LINES-2, COLS-20, dialog_attr, border_attr);
+ wattrset(fs_win, dialog_attr);
+ if (is_fselect) {
+ mvwaddstr(fs_win, 0, (COLS-20)/2 - 7, " File Select ");
+ } else {
+ mvwaddstr(fs_win, 0, (COLS-20)/2 - 9, " Directory Select ");
+ }
+ draw_shadow(stdscr, 1, 10, LINES-2, COLS-20);
+ display_helpline(fs_win, LINES-3, COLS-20);
+
+ /* Filemask entry */
+ strcpy(o_fm, fmask);
+ fm_obj = NewStringObj(fs_win, "Filemask:", o_fm, 1, 2, 19, 255);
+ AddObj(&obj, STRINGOBJ, (void *) fm_obj);
+
+ /* Directory entry */
+ dir_obj = NewStringObj(fs_win, "Directory:", o_dir, 1, 22, COLS-44, 255);
+ AddObj(&obj, STRINGOBJ, (void *) dir_obj);
+
+ /* Directory list */
+ get_dir(".", fmask, &d, &n); /* read the entire directory */
+ get_directories(d, n, &dnames, &nd); /* extract the dir-entries */
+ if (is_fselect) {
+ dirs_obj = NewListObj(fs_win, "Directories:", dnames, o_dir, 5, 2,
+ LINES-16, (COLS-20)/2-2, nd);
+ } else {
+ dirs_obj = NewListObj(fs_win, "Directories:", dnames, o_dir, 5, 2,
+ LINES-12, (COLS-20)/2-2, nd);
+ }
+ AddObj(&obj, LISTOBJ, (void *) dirs_obj);
+
+ /* Filenames list */
+ get_filenames(d, n, &fnames, &nf); /* extract the filenames */
+ if (is_fselect) {
+ files_obj = NewListObj(fs_win, "Files:", fnames, o_sel, 5, (COLS-20)/2+1,
+ LINES-16, (COLS-20)/2-3, nf);
+ } else {
+ files_obj = NewListObj(fs_win, "Files:", fnames, o_sel, 5, (COLS-20)/2+1,
+ LINES-12, (COLS-20)/2-3, nf);
+ }
+ AddObj(&obj, LISTOBJ, (void *) files_obj);
+
+ if (is_fselect) {
+ /* Selection entry */
+ o_sel[0] = '\0';
+ sel_obj = NewStringObj(fs_win, "Selection:", o_sel, LINES-10, 2, COLS-24, 255);
+ AddObj(&obj, STRINGOBJ, (void *) sel_obj);
+ }
+
+ /* Ok button */
+ ok_button = FALSE;
+ okbut_obj = NewButtonObj(fs_win, "Ok", &ok_button, LINES-6, 20);
+ AddObj(&obj, BUTTONOBJ, (void *) okbut_obj);
+
+ /* Cancel button */
+ cancel_button = FALSE;
+ canbut_obj = NewButtonObj(fs_win, "Cancel", &cancel_button, LINES-6, 30);
+ AddObj(&obj, BUTTONOBJ, (void *) canbut_obj);
+
+ /* Make sure all objects on the window are drawn */
+ wrefresh(fs_win);
+ keypad(fs_win, TRUE);
+
+ /* Start the reading */
+ o = obj;
+ strcpy(old_fmask, o_fm);
+ strcpy(old_dir, o_dir);
+ quit = FALSE;
+ cancel = FALSE;
+ while (!quit) {
+ ret = PollObj(&o);
+ switch(ret) {
+ case SEL_CR:
+ if (strcmp(old_fmask, o_fm) || strcmp(old_dir, o_dir)) {
+ /* reread directory and update the listobjects */
+ if (strcmp(old_dir, o_dir)) { /* dir entry was changed */
+ if (chdir(o_dir)) {
+ dialog_notify("Could not change into directory");
+ } else {
+ getcwd(o_dir, MAXPATHLEN);
+ strcpy(old_dir, o_dir);
+ RefreshStringObj(dir_obj);
+ }
+ } else { /* fmask entry was changed */
+ strcpy(old_fmask, o_fm);
+ }
+ get_dir(".", o_fm, &d, &n);
+ FreeNames(dnames, nd);
+ get_directories(d, n, &dnames, &nd);
+ UpdateListObj(dirs_obj, dnames, nd);
+ FreeNames(fnames, nf);
+ get_filenames(d, n, &fnames, &nf);
+ UpdateListObj(files_obj, fnames, nf);
+ if (((o->prev)->obj == (void *) dirs_obj)) {
+ o=o->prev;
+ }
+ }
+ break;
+ case SEL_BUTTON:
+ /* check which button was pressed */
+ if (ok_button) {
+ quit = TRUE;
+ }
+ if (cancel_button) {
+ quit = TRUE;
+ cancel = TRUE;
+ }
+ break;
+ case SEL_ESC:
+ quit = TRUE;
+ cancel = TRUE;
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+ DelObj(obj);
+ FreeNames(dnames, nd);
+ FreeNames(fnames, nf);
+ delwin(fs_win);
+
+ if (cancel || (strlen(o_sel) == 0)) {
+ return(NULL);
+ } else {
+ ret_name = (char *) malloc( strlen(o_sel) + 1 );
+ strcpy(ret_name, o_sel);
+ return(ret_name);
+ }
+} /* dialog_fselect() */
+
diff --git a/gnu/lib/libdialog/gauge.c b/gnu/lib/libdialog/gauge.c
new file mode 100644
index 0000000..a44f969
--- /dev/null
+++ b/gnu/lib/libdialog/gauge.c
@@ -0,0 +1,72 @@
+/*
+ * gauge.c
+ *
+ * progress indicator for libdialog
+ *
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ */
+
+#include "dialog.h"
+
+void
+dialog_gauge(char *title, char *prompt, int y, int x,
+ int height, int width, int perc)
+/*
+ * Desc: display a progress bar, progress indicated by <perc>
+ */
+{
+ WINDOW *gw;
+ int glen, i;
+ char percs[5];
+
+ gw = newwin(height, width, y, x);
+ if (!gw) {
+ fprintf(stderr, "dialog_gauge: Error creating window (%d, %d, %d, %d)",
+ height, width, y, x);
+ exit(-1);
+ }
+
+ draw_box(gw, 0, 0, height, width, dialog_attr, border_attr);
+ draw_shadow(stdscr, y, x, height, width);
+
+ wattrset(gw, title_attr);
+ if (title) {
+ wmove(gw, 0, (width - strlen(title))/2 - 1);
+ waddstr(gw, "[ ");
+ waddstr(gw, title);
+ waddstr(gw, " ]");
+ }
+ wattrset(gw, dialog_attr);
+ if (prompt) {
+ wmove(gw, 1, (width - strlen(prompt))/2 - 1);
+ waddstr(gw, prompt);
+ }
+
+ draw_box(gw, 2, 2, 3, width-4, dialog_attr, border_attr);
+ glen = (int) ((float) perc/100 * (width-6));
+
+ wattrset(gw, dialog_attr);
+ sprintf(percs, "%3d%%", perc);
+ wmove(gw, 5, width/2 - 2);
+ waddstr(gw, percs);
+
+ wattrset(gw, A_BOLD);
+ wmove(gw, 3, 3);
+ for (i=0; i<glen; i++) waddch(gw, ' ');
+
+ wrefresh(gw);
+
+ return;
+} /* dialog_gauge() */
+
diff --git a/gnu/lib/libdialog/help.c b/gnu/lib/libdialog/help.c
new file mode 100644
index 0000000..de49c6a
--- /dev/null
+++ b/gnu/lib/libdialog/help.c
@@ -0,0 +1,194 @@
+/***************************************************************
+ *
+ * Program: help.c
+ * Author: Marc van Kempen
+ * Desc: get help
+ *
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ ***************************************************************/
+
+#include <stdlib.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <dialog.h>
+
+static char _helpfilebuf[MAXPATHLEN];
+static char _helplinebuf[77]; /* limit the helpline to 76 characters */
+static char *_helpfile = NULL;
+static char *_helpline = NULL;
+
+/******************************************************************
+ *
+ * helpfile routines
+ *
+ ******************************************************************/
+
+void
+use_helpfile(char *hfile)
+/*
+ * desc: set the helpfile to be opened on pressing F1 to <helpfile>
+ */
+{
+ if (hfile != NULL) {
+ _helpfile = _helpfilebuf;
+ strcpy(_helpfile, hfile);
+ } else {
+ _helpfile = NULL;
+ }
+
+ return;
+} /* use_helpfile() */
+
+void
+display_helpfile(void)
+/*
+ * desc: display the current helpfile in a window
+ */
+{
+ WINDOW *w;
+ FILE *f;
+ struct stat sb;
+ char msg[80], *buf;
+ static int in_help = FALSE;
+ char *savehline = NULL;
+
+ if (in_help) return; /* dont call help when you're in help */
+
+ if (_helpfile != NULL) {
+ if ((w = dupwin(newscr)) == NULL) {
+ dialog_notify("No memory to dup previous screen\n");
+ return;
+ }
+ if ((f = fopen(_helpfile, "r")) == NULL) {
+ sprintf(msg, "Can't open helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if (fstat(fileno(f), &sb)) {
+ sprintf(msg, "Can't stat helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if ((buf = (char *) malloc( sb.st_size )) == NULL) {
+ sprintf(msg, "Could not malloc space for helpfile : %s\n", _helpfile);
+ dialog_notify(msg);
+ return;
+ }
+ if (fread(buf, 1, sb.st_size, f) != sb.st_size) {
+ sprintf(msg, "Could not read entire help file : %s", _helpfile);
+ dialog_notify(msg);
+ free(buf);
+ return;
+ }
+ buf[sb.st_size] = 0;
+ in_help = TRUE;
+ savehline = get_helpline();
+ use_helpline("Use arrowkeys, PgUp, PgDn, Home and End to move through text");
+ dialog_mesgbox("Online help", buf, LINES-4, COLS-4);
+ restore_helpline(savehline);
+ in_help = FALSE;
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+ free(buf);
+ } else {
+ /* do nothing */
+ }
+
+ return;
+} /* display_helpfile() */
+
+
+/******************************************************************
+ *
+ * helpline routines
+ *
+ ******************************************************************/
+
+void
+use_helpline(char *hline)
+/*
+ * desc: set the helpline to printed in dialogs
+ */
+{
+ if (hline) {
+ _helpline = _helplinebuf;
+ if (strlen(hline) > 76) {
+ /* only display the first 76 characters in the helpline */
+ strncpy(_helpline, hline, 76);
+ _helpline[76] = 0;
+ } else {
+ strcpy(_helpline, hline);
+ }
+ } else {
+ _helpline = NULL;
+ }
+
+ return;
+} /* use_helpline() */
+
+void
+display_helpline(WINDOW *w, int y, int width)
+/*
+ * desc: display the helpline at the given coordinates <y, x> in the window <w>
+ */
+{
+ if (_helpline != NULL) {
+ if (strlen(_helpline) > width - 6) {
+ _helpline[width - 6] = 0;
+ }
+ wmove(w, y, (int) (width - strlen(_helpline)- 4) / 2);
+ wattrset(w, title_attr);
+ waddstr(w, "[ ");
+ waddstr(w, _helpline);
+ waddstr(w, " ]");
+ } else {
+ /* do nothing */
+ }
+
+ return;
+}
+
+char *
+get_helpline(void)
+/*
+ * desc: allocate new space, copy the helpline to it and return a pointer to it
+ */
+{
+ char *hlp;
+
+ if (_helpline) {
+ hlp = (char *) malloc( strlen(_helpline) + 1 );
+ strcpy(hlp, _helpline);
+ } else {
+ hlp = NULL;
+ }
+
+ return(hlp);
+} /* get_helpline() */
+
+void
+restore_helpline(char *helpline)
+/*
+ * Desc: set the helpline to <helpline> and free the space allocated to it
+ */
+{
+ use_helpline(helpline);
+ free(helpline);
+
+ return;
+} /* restore_helpline() */
diff --git a/gnu/lib/libdialog/inputbox.c b/gnu/lib/libdialog/inputbox.c
new file mode 100644
index 0000000..fc9a40c
--- /dev/null
+++ b/gnu/lib/libdialog/inputbox.c
@@ -0,0 +1,190 @@
+/*
+ * inputbox.c -- implements the input box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result)
+{
+ int i, j, x, y, box_y, box_x, box_width, first,
+ key = 0, button = -1;
+ unsigned char instr[MAX_LEN+1];
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j) + 4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ /* Draw the input field box */
+ box_width = width-6;
+ getyx(dialog, y, x);
+ box_y = y + 2;
+ box_x = (width - box_width)/2;
+ draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-11;
+ y = height-2;
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+
+ first = 1;
+ strcpy(instr, result);
+ wattrset(dialog, dialog_attr);
+
+ while (key != ESC) {
+
+ if (button == -1) { /* Input box selected */
+ key = line_edit(dialog, box_y, box_x, -1, box_width, inputbox_attr, first, instr);
+ first = 0;
+ }
+ else
+ key = wgetch(dialog);
+
+ switch (key) {
+ case 'O':
+ case 'o':
+ delwin(dialog);
+ strcpy(result, instr);
+ return 0;
+ case 'C':
+ case 'c':
+ delwin(dialog);
+ return 1;
+ case KEY_UP:
+ case KEY_LEFT:
+ case KEY_BTAB:
+ switch (button) {
+ case -1:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = -1; /* Indicates input box is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ break;
+ case 1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+ break;
+ }
+ break;
+ case TAB:
+ case KEY_DOWN:
+ case KEY_RIGHT:
+ switch (button) {
+ case -1:
+ button = 0; /* Indicates "OK" button is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ wrefresh(dialog);
+ break;
+ case 0:
+ button = 1; /* Indicates "Cancel" button is selected */
+ print_button(dialog, " OK ", y, x, FALSE);
+ print_button(dialog, "Cancel", y, x+14, TRUE);
+ wrefresh(dialog);
+ break;
+ case 1:
+ button = -1; /* Indicates input box is selected */
+ print_button(dialog, "Cancel", y, x+14, FALSE);
+ print_button(dialog, " OK ", y, x, TRUE);
+ break;
+ }
+ break;
+ case ' ':
+ case '\n':
+ case '\r':
+ delwin(dialog);
+ if (button < 1)
+ strcpy(result, instr);
+ return (button == -1 ? 0 : button);
+ case ESC:
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_inputbox() */
diff --git a/gnu/lib/libdialog/kernel.c b/gnu/lib/libdialog/kernel.c
new file mode 100644
index 0000000..7a67af6
--- /dev/null
+++ b/gnu/lib/libdialog/kernel.c
@@ -0,0 +1,524 @@
+/*
+ * dialog - Display simple dialog boxes from shell scripts
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * HISTORY:
+ *
+ * 17/12/93 - Version 0.1 released.
+ *
+ * 19/12/93 - menu will now scroll if there are more items than can fit
+ * on the screen.
+ * - added 'checklist', a dialog box with a list of options that
+ * can be turned on or off. A list of options that are on is
+ * returned on exit.
+ *
+ * 20/12/93 - Version 0.15 released.
+ *
+ * 29/12/93 - Incorporated patch from Patrick J. Volkerding
+ * (volkerdi@mhd1.moorhead.msus.edu) that made these changes:
+ * - increased MAX_LEN to 2048
+ * - added 'infobox', equivalent to a message box without pausing
+ * - added option '--clear' that will clear the screen
+ * - Explicit line breaking when printing prompt text can be
+ * invoked by real newline '\n' besides the string "\n"
+ * - an optional parameter '--title <string>' can be used to
+ * specify a title string for the dialog box
+ *
+ * 03/01/94 - added 'textbox', a dialog box for displaying text from a file.
+ * - Version 0.2 released.
+ *
+ * 04/01/94 - some fixes and improvements for 'textbox':
+ * - fixed a bug that will cause a segmentation violation when a
+ * line is longer than MAX_LEN characters. Lines will now be
+ * truncated if they are longer than MAX_LEN characters.
+ * - removed wrefresh() from print_line(). This will increase
+ * efficiency of print_page() which calls print_line().
+ * - display current position in the form of percentage into file.
+ * - Version 0.21 released.
+ *
+ * 05/01/94 - some changes for faster screen update.
+ *
+ * 07/01/94 - much more flexible color settings. Can use all 16 colors
+ * (8 normal, 8 highlight) of the Linux console.
+ *
+ * 08/01/94 - added run-time configuration using configuration file.
+ *
+ * 09/01/94 - some minor bug fixes and cleanups for menubox, checklist and
+ * textbox.
+ *
+ * 11/01/94 - added a man page.
+ *
+ * 13/01/94 - some changes for easier porting to other Unix systems (tested
+ * on Ultrix, SunOS and HPUX)
+ * - Version 0.3 released.
+ *
+ * 08/06/94 - Patches by Stuart Herbert - S.Herbert@shef.ac.uk
+ * Fixed attr_clear and the textbox stuff to work with ncurses 1.8.5
+ * Fixed the wordwrap routine - it'll actually wrap properly now
+ * Added a more 3D look to everything - having your own rc file could
+ * prove 'interesting' to say the least :-)
+ * Added radiolist option
+ * - Version 0.4 released.
+ */
+
+#define __DIALOG_MAIN__
+
+#include <dialog.h>
+#include "dialog.priv.h"
+#ifdef HAVE_NCURSES
+#include "colors.h"
+#endif
+
+/* These are two "secret" globals that can be fiddled to make a dialog
+ * come up someplace other than a "centered" calculation for X,Y
+ */
+int DialogX, DialogY;
+
+/*
+ * Do some initialization for dialog
+ */
+void init_dialog(void)
+{
+#if defined(LOCALE)
+ (void) setlocale(LC_ALL, "");
+#endif
+
+#ifdef HAVE_NCURSES
+ if (parse_rc() == -1) /* Read the configuration file */
+ exit(-1);
+#endif
+
+ if (initscr() == NULL) { /* Init curses */
+ fprintf(stderr, "\nCurses initialization error.\n");
+ exit(-1);
+ }
+ keypad(stdscr, TRUE);
+ cbreak();
+ noecho();
+
+#ifdef HAVE_NCURSES
+ if (use_colors || use_shadow) /* Set up colors */
+ color_setup();
+#endif
+
+ /* Set screen to screen attribute */
+ dialog_clear_norefresh();
+ DialogX = DialogY = 0;
+}
+/* End of init_dialog() */
+
+
+#ifdef HAVE_NCURSES
+/*
+ * Setup for color display
+ */
+void color_setup(void)
+{
+ int i;
+
+ if (has_colors()) { /* Terminal supports color? */
+ start_color();
+
+ /* Initialize color pairs */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ init_pair(i+1, color_table[i][0], color_table[i][1]);
+
+ /* Setup color attributes */
+ for (i = 0; i < ATTRIBUTE_COUNT; i++)
+ attributes[i] = C_ATTR(color_table[i][2], i+1);
+ }
+}
+/* End of color_setup() */
+#endif
+
+
+/*
+ * Set window to attribute 'attr'
+ */
+void attr_clear(WINDOW *win, int height, int width, chtype attr)
+{
+ int i, j;
+
+ wattrset(win, attr); /* Set window to attribute 'attr' */
+ for (i = 0; i < height; i++) {
+ wmove(win, i, 0);
+ for (j = 0; j < width; j++)
+ waddch(win, ' ');
+ }
+}
+/* End of attr_clear() */
+
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Note that the
+ * string may contain "\n" to represent a newline character or the real
+ * newline '\n', but in that case, auto wrap around will be disabled.
+ */
+void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, int maxwidth, int y, int x, int center, int rawmode)
+{
+ int cur_x, cur_y, i;
+ unsigned char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
+ chtype ostuff[132], attrs = 0, init_bottom = 0;
+
+ wsetscrreg(win, y, height);
+ getyx(win, cur_y, cur_x);
+
+ strncpy(tempstr, prompt, MAX_LEN);
+ tempstr[MAX_LEN] = '\0';
+ if ((!rawmode && strstr(tempstr, "\\n") != NULL) ||
+ (strchr(tempstr, '\n') != NULL)) { /* Prompt contains "\n" or '\n' */
+ word = tempstr;
+ while (1) {
+ tempptr = rawmode ? NULL : strstr(word, "\\n");
+ tempptr1 = strchr(word, '\n');
+ if (tempptr == NULL && tempptr1 == NULL)
+ break;
+ else if (tempptr == NULL) { /* No more "\n" */
+ tempptr = tempptr1;
+ tempptr[0] = '\0';
+ }
+ else if (tempptr1 == NULL) { /* No more '\n' */
+ tempptr[0] = '\0';
+ tempptr++;
+ }
+ else { /* Prompt contains both "\n" and '\n' */
+ if (strlen(tempptr)-2 < strlen(tempptr1)-1) {
+ tempptr = tempptr1;
+ tempptr[0] = '\0';
+ }
+ else {
+ tempptr[0] = '\0';
+ tempptr++;
+ }
+ }
+
+ waddstr(win, word);
+ word = tempptr + 1;
+ if (++cur_y > height) {
+ cur_y--;
+ if (!init_bottom) {
+ for (i = 0; i < x; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ for (i = width; i < maxwidth; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ attrs = getattrs(win);
+ init_bottom = 1;
+ }
+ scrollok(win, TRUE);
+ scroll(win);
+ scrollok(win, FALSE);
+ wmove(win, cur_y, 0);
+ for (i = 0; i < x; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ for ( ; i < width; i++)
+ waddch(win, ' ');
+ for ( ; i < maxwidth; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ wrefresh(win);
+ }
+ wmove(win, cur_y, cur_x = x);
+ }
+ waddstr(win, word);
+ }
+ else if (center && strlen(tempstr) <= width-x*2) { /* If prompt is short */
+ wmove(win, cur_y, (width - strlen(tempstr)) / 2);
+ waddstr(win, tempstr);
+ }
+ else if (!center && strlen(tempstr) <= width-cur_x) { /* If prompt is short */
+ waddstr(win, tempstr);
+ }
+ else {
+ char *p = tempstr;
+
+ /* Print prompt word by word, wrap around if necessary */
+ while ((word = strsep(&p, "\t\n ")) != NULL) {
+ int loop;
+ unsigned char sc;
+
+ if (*word == '\0')
+ continue;
+ do {
+ loop = 0;
+ if (cur_x+strlen(word) >= width+1) { /* wrap around to next line */
+ if (x+strlen(word) >= width+1) {
+ sc = word[width-cur_x-1];
+ word[width-cur_x-1] = '\0';
+ wmove(win, cur_y, cur_x);
+ waddstr(win, word);
+ word[width-cur_x-1] = sc;
+ word += width-cur_x-1;
+ getyx(win, cur_y, cur_x);
+ loop = 1;
+ }
+ cur_y++;
+ cur_x = x;
+ if (cur_y > height) {
+ cur_y--;
+ if (!init_bottom) {
+ for (i = 0; i < x; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ for (i = width; i < maxwidth; i++)
+ ostuff[i] = mvwinch(win, cur_y, i);
+ attrs = getattrs(win);
+ init_bottom = 1;
+ }
+ scrollok(win, TRUE);
+ scroll(win);
+ scrollok(win, FALSE);
+ wmove(win, cur_y, 0);
+ for (i = 0; i < x; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ for ( ; i < width; i++)
+ waddch(win, ' ');
+ for ( ; i < maxwidth; i++) {
+ wattrset(win, ostuff[i]&A_ATTRIBUTES);
+ waddch(win, ostuff[i]);
+ }
+ wattrset(win, attrs);
+ wrefresh(win);
+ }
+ }
+ }
+ while(loop);
+ wmove(win, cur_y, cur_x);
+ waddstr(win, word);
+ getyx(win, cur_y, cur_x);
+ cur_x++;
+ }
+ }
+}
+/* End of print_autowrap() */
+
+
+/*
+ * Print a button
+ */
+void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected)
+{
+ int i, temp;
+
+ wmove(win, y, x);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, selected ? "[" : " ");
+ temp = strspn(label, " ");
+ label += temp;
+ for (i = 0; i < temp; i++)
+ waddch(win, ' ');
+ wattrset(win, selected ? button_key_active_attr : button_key_inactive_attr);
+ waddch(win, label[0]);
+ wattrset(win, selected ? button_active_attr : button_inactive_attr);
+ waddstr(win, label+1);
+ waddstr(win, selected ? "]" : " ");
+ wmove(win, y, x+temp+1);
+}
+/* End of print_button() */
+
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chtype border)
+{
+ int i, j;
+
+ wattrset(win, 0);
+ for (i = 0; i < height; i++) {
+ wmove(win, y + i, x);
+ for (j = 0; j < width; j++)
+ if (!i && !j)
+ waddch(win, border | ACS_ULCORNER);
+ else if (i == height-1 && !j)
+ waddch(win, border | ACS_LLCORNER);
+ else if (!i && j == width-1)
+ waddch(win, box | ACS_URCORNER);
+ else if (i == height-1 && j == width-1)
+ waddch(win, box | ACS_LRCORNER);
+ else if (!i)
+ waddch(win, border | ACS_HLINE);
+ else if (i == height-1)
+ waddch(win, box | ACS_HLINE);
+ else if (!j)
+ waddch(win, border | ACS_VLINE);
+ else if (j == width-1)
+ waddch(win, box | ACS_VLINE);
+ else
+ waddch(win, box | ' ');
+ }
+}
+/* End of draw_box() */
+
+
+#ifdef HAVE_NCURSES
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void draw_shadow(WINDOW *win, int y, int x, int height, int width)
+{
+ int i,sx,sy;
+ chtype attrs;
+
+ if (has_colors()) { /* Whether terminal supports color? */
+ getbegyx(win,sy,sx);
+ attrs = getattrs(win);
+ if (y+height < getmaxy(win)) {
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ if (i+x+2 < getmaxx(win))
+ waddch(win, ' ');
+ /* end touch */
+ wattrset(win, shadow_attr);
+ wmove(win, y + height, x + 2);
+ for (i = 0; i < width; i++)
+ if (i+x+2 < getmaxx(win))
+ waddch(win, mvwinch(newscr, sy+y+height, sx+x+2+i) & A_CHARTEXT);
+ }
+ if (x+width < getmaxx(win)) {
+ for (i = y + 1; i < y + height + 1; i++) {
+ if (i < getmaxy(win)) {
+ /* small touch */
+ wattrset(win, A_INVIS);
+ wmove(win, i, x + width);
+ waddch(win, ' ');
+ if (x+width+1 < getmaxx(win))
+ waddch(win, ' ');
+ /* end touch */
+ wattrset(win, shadow_attr);
+ wmove(win, i, x + width);
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width) & A_CHARTEXT);
+ if (x+width+1 < getmaxx(win))
+ waddch(win, mvwinch(newscr, sy+i, sx+x+width+1) & A_CHARTEXT);
+ }
+ }
+ }
+ wattrset(win, attrs);
+ wnoutrefresh(win);
+ }
+}
+/* End of draw_shadow() */
+#endif
+
+void dialog_clear_norefresh(void)
+{
+ attr_clear(stdscr, LINES, COLS, screen_attr);
+ touchwin(stdscr);
+ wnoutrefresh(stdscr);
+}
+
+void dialog_clear(void)
+{
+ dialog_clear_norefresh();
+ doupdate();
+}
+
+void dialog_update(void)
+{
+ refresh();
+}
+
+void end_dialog(void)
+{
+ endwin();
+}
+
+int strwidth(const char *p)
+{
+ int i = 0, len, incr;
+ const char *start, *s, *s1, *s2;
+
+ for (start = s = p; ; start = (s += incr)) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ len = s - start;
+ if (len > i)
+ i = len;
+ }
+ len = strlen(start);
+ if (len > i)
+ i = len;
+ return i;
+}
+
+int strheight(const char *p)
+{
+ int i = 1, incr;
+ const char *s, *s1, *s2;
+
+ for (s = p; ; s += incr) {
+ s1 = strchr(s, '\n');
+ s2 = strstr(s, "\\n");
+ if (s2 == NULL)
+ s = s1;
+ else if (s1 == NULL)
+ s = s2;
+ else
+ s = MIN(s1, s2);
+ if (s == NULL)
+ break;
+ incr = 1 + (s == s2);
+ i++;
+ }
+ return i;
+}
+
+void print_arrows(WINDOW *dialog, int scroll, int menu_height, int item_no,
+ int box_x, int box_y, int tag_x, int cur_x, int cur_y)
+{
+ wmove(dialog, box_y, box_x + tag_x + 1);
+ wattrset(dialog, scroll ? uarrow_attr : menubox_attr);
+ waddch(dialog, scroll ? ACS_UARROW : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 2);
+ waddch(dialog, scroll ? '(' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 3);
+ waddch(dialog, scroll ? '-' : ACS_HLINE);
+ wmove(dialog, box_y, box_x + tag_x + 4);
+ waddch(dialog, scroll ? ')' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 1);
+ wattrset(dialog, scroll+menu_height < item_no ? darrow_attr : menubox_border_attr);
+ waddch(dialog, scroll+menu_height < item_no ? ACS_DARROW : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 2);
+ waddch(dialog, scroll+menu_height < item_no ? '(' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 3);
+ waddch(dialog, scroll+menu_height < item_no ? '+' : ACS_HLINE);
+ wmove(dialog, box_y + menu_height + 1, box_x + tag_x + 4);
+ waddch(dialog, scroll+menu_height < item_no ? ')' : ACS_HLINE);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+}
+
diff --git a/gnu/lib/libdialog/lineedit.c b/gnu/lib/libdialog/lineedit.c
new file mode 100644
index 0000000..8c33e8b
--- /dev/null
+++ b/gnu/lib/libdialog/lineedit.c
@@ -0,0 +1,213 @@
+/*
+ * Changes Copyright (C) 1995 by Andrey A. Chernov, Moscow
+ *
+ * Original Copyright:
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+static void redraw_field(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, unsigned char instr[], int input_x, int scroll, chtype attr, chtype old_attr, int fexit);
+
+/*
+ * Line editor
+ */
+int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, chtype attr, int first, unsigned char *result)
+{
+ int i, key;
+ chtype old_attr;
+ static int input_x, scroll;
+ static unsigned char instr[MAX_LEN+1];
+ unsigned char erase_char = erasechar();
+ unsigned char kill_char = killchar();
+#ifdef notyet
+ unsignec char werase_char = cur_term->Ottyb.c_cc[VWERASE];
+#endif
+
+ old_attr = getattrs(dialog);
+ keypad(dialog, TRUE);
+
+ if (first) {
+ memset(instr, 0, sizeof(instr));
+ strcpy(instr, result);
+ i = strlen(instr);
+/* input_x = i % box_width;*/
+ input_x = (i > box_width) ? box_width - 1 : i;
+/* scroll = i - input_x;*/
+ scroll = (i > box_width) ? i - box_width + 1: 0;
+ }
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+
+ for (;;) {
+ wattrset(dialog, attr);
+ wrefresh(dialog);
+ key = wgetch(dialog);
+ switch (key) {
+ case ctrl('q'):
+ goto ret;
+ break;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ case TAB:
+ case KEY_BTAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case ESC:
+ case '\r':
+ case '\n':
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ if (key == '\r')
+ key = '\n';
+ goto ret;
+ case '\025':
+ case '\030':
+ kill_it:
+ input_x = scroll = 0;
+ /* fall through */
+ case '\013':
+ case KEY_EOL:
+ memset(instr + scroll + input_x, '\0', sizeof(instr) - scroll - input_x);
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ continue;
+ case '\001':
+ case KEY_HOME:
+ input_x = scroll = 0;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ continue;
+ case '\005':
+ case KEY_END:
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ input_x = i % box_width;
+ scroll = i - input_x;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ continue;
+ case '\002':
+ case KEY_LEFT:
+ if (input_x || scroll) {
+ if (!input_x) {
+ int oldscroll = scroll;
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ input_x = oldscroll - 1 - scroll;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ } else {
+ input_x--;
+ wmove(dialog, box_y, input_x + box_x);
+ }
+ } else
+ beep();
+ continue;
+ case '\006':
+ case KEY_RIGHT:
+ if ( scroll+input_x < MAX_LEN
+ && (flen < 0 || scroll+input_x < flen)
+ ) {
+ if (!instr[scroll+input_x])
+ instr[scroll+input_x] = ' ';
+ if (input_x == box_width-1) {
+ scroll++;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ }
+ else {
+ wmove(dialog, box_y, input_x + box_x);
+ waddch(dialog, instr[scroll+input_x]);
+ input_x++;
+ }
+ } else
+ beep(); /* Alarm user about overflow */
+ continue;
+ case '\b':
+ case '\177':
+ case KEY_BACKSPACE:
+ erase_it:
+ if (input_x || scroll) {
+ i = strlen(instr);
+ memmove(instr+scroll+input_x-1, instr+scroll+input_x, i-(scroll+input_x)+1);
+ if (!input_x) {
+ int oldscroll = scroll;
+ scroll = scroll < box_width-1 ? 0 : scroll-(box_width-1);
+ input_x = oldscroll - 1 - scroll;
+ } else
+ input_x--;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ } else
+ beep();
+ continue;
+ case '\004':
+ case KEY_DC:
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ if (i == 0) {
+ beep();
+ continue;
+ }
+ memmove(instr+scroll+input_x, instr+scroll+input_x+1, i-(scroll+input_x));
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ continue;
+ default:
+ if (CCEQ(key, erase_char))
+ goto erase_it;
+ if (CCEQ(key, kill_char))
+ goto kill_it;
+ if (key < 0x100 && isprint(key)) {
+ for (i = strlen(instr) - 1; i >= scroll + input_x && instr[i] == ' '; i--)
+ instr[i] = '\0';
+ i++;
+ if (i < MAX_LEN && (flen < 0 || scroll+input_x < flen)) {
+ if (flen < 0 || i < flen)
+ memmove(instr+scroll+input_x+1, instr+scroll+input_x, i-(scroll+input_x));
+ instr[scroll+input_x] = key;
+ if (input_x == box_width-1 && (flen < 0 || i < flen))
+ scroll++;
+ else
+ input_x++;
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, FALSE);
+ } else
+ beep(); /* Alarm user about overflow */
+ continue;
+ }
+ }
+ }
+ret:
+ redraw_field(dialog, box_y, box_x, flen, box_width, instr, input_x, scroll, attr, old_attr, TRUE);
+ wrefresh(dialog);
+ strcpy(result, instr);
+ return key;
+}
+
+static void
+redraw_field(WINDOW *dialog, int box_y, int box_x, int flen, int box_width, unsigned char instr[], int input_x, int scroll, chtype attr, chtype old_attr, int fexit)
+{
+ int i, fix_len;
+
+ wattrset(dialog, fexit ? old_attr : attr);
+ wmove(dialog, box_y, box_x);
+ fix_len = flen >= 0 ? MIN(flen-scroll,box_width) : box_width;
+ for (i = 0; i < fix_len; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wattrset(dialog, old_attr);
+ for ( ; i < box_width; i++)
+ waddch(dialog, instr[scroll+i] ? instr[scroll+i] : ' ');
+ wmove(dialog, box_y, input_x + box_x);
+}
diff --git a/gnu/lib/libdialog/menubox.c b/gnu/lib/libdialog/menubox.c
new file mode 100644
index 0000000..3755d82
--- /dev/null
+++ b/gnu/lib/libdialog/menubox.c
@@ -0,0 +1,454 @@
+/*
+ * menubox.c -- implements the menu box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+#include <ncurses.h>
+
+static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected,
+ dialogMenuItem *me);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+static int menu_width, tag_x, item_x;
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height,
+ int cnt, void *it, unsigned char *result, int *ch, int *sc)
+{
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice, item_no, redraw_menu = FALSE;
+ char okButton, cancelButton;
+ WINDOW *dialog, *menu;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+
+draw:
+ if (ch) /* restore menu item info */
+ choice = *ch;
+ if (sc)
+ scroll = *sc;
+
+ /* If item_no is a positive integer, use old item specification format */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 2) * sizeof(unsigned char *));
+
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ items[i*2] = ditems[i].prompt;
+ items[i*2 + 1] = ditems[i].title;
+ }
+ }
+ max_choice = MIN(menu_height, item_no);
+
+ tag_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center menu */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*2]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*2 + 1]);
+ tag_x = MAX(tag_x, l + k + 2);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+menu_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j);
+ width = MAX(width,tag_x+4)+4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ return -1;
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ menu_width = width-6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - menu_width)/2 - 1;
+
+ /* create new window for the menu */
+ menu = subwin(dialog, menu_height, menu_width, y + box_y + 1, x + box_x + 1);
+ if (menu == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", menu_height,menu_width,y+box_y+1,x+box_x+1);
+ return -1;
+ }
+ keypad(menu, TRUE);
+
+ /* draw a box around the menu items */
+ draw_box(dialog, box_y, box_x, menu_height+2, menu_width+2, menubox_border_attr, menubox_attr);
+
+ tag_x = (menu_width - tag_x) / 2;
+ item_x = tag_x + item_x + 2;
+
+ /* Print the menu */
+ for (i = 0; i < max_choice; i++)
+ print_item(menu, items[(scroll+i)*2], items[(scroll+i)*2 + 1], i, i == choice, DREF(ditems, scroll + i));
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-11;
+ y = height-2;
+
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* Shortcut to OK? */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result)
+ strcpy(result, items[(scroll + choice) * 2]);
+ delwin(menu);
+ delwin(dialog);
+ return 0;
+ }
+ /* Shortcut to cancel? */
+ else if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ delwin(menu);
+ delwin(dialog);
+ return 1;
+ }
+
+ /* Check if key pressed matches first character of any item tag in menu */
+ for (i = 0; i < max_choice; i++)
+ if (key < 0x100 && toupper(key) == toupper(items[(scroll+i)*2][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
+ key == KEY_UP || key == KEY_DOWN || key == '-' || key == '+') {
+ if (key >= '1' && key <= MIN('9', '0'+max_choice))
+ i = key - '1';
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+ /* Scroll menu down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (menu_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, FALSE, DREF(ditems, scroll));
+ scrollok(menu, TRUE);
+ wscrl(menu, -1);
+ scrollok(menu, FALSE);
+ }
+ scroll--;
+ print_item(menu, items[scroll*2], items[scroll*2 + 1], 0, TRUE, DREF(ditems, scroll));
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+')
+ if (choice == max_choice - 1) {
+ if (scroll+choice < item_no-1) {
+ /* Scroll menu up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (menu_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(menu, items[(scroll + max_choice - 1) * 2], items[(scroll + max_choice - 1) * 2 + 1],
+ max_choice-1, FALSE, DREF(ditems, scroll + max_choice - 1));
+ scrollok(menu, TRUE);
+ scroll(menu);
+ scrollok(menu, FALSE);
+ }
+ scroll++;
+ print_item(menu, items[(scroll + max_choice - 1) * 2], items[(scroll + max_choice - 1) * 2 + 1],
+ max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(menu, items[(scroll + choice) * 2], items[(scroll + choice) * 2 + 1], choice, FALSE,
+ DREF(ditems, scroll + choice));
+
+ /* Highlight new item */
+ choice = i;
+ print_item(menu, items[(scroll + choice) * 2], items[(scroll + choice) * 2 + 1], choice, TRUE,
+ DREF(ditems, scroll + choice));
+ wnoutrefresh(menu);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ /* save info about menu item position */
+ if (ch)
+ *ch = choice;
+ if (sc)
+ *sc = scroll;
+
+ switch (key) {
+ case KEY_PPAGE:
+ if (scroll > height-4) { /* can we go up? */
+ scroll -= (height-4);
+ } else {
+ scroll = 0;
+ }
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_NPAGE:
+ if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */
+ scroll = item_no - menu_height;
+ if (scroll < 0) scroll = 0;
+ } else {
+ scroll += menu_height;
+ }
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_HOME:
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_END:
+ scroll = item_no - menu_height;
+ if (scroll < 0) scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_BTAB:
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wrefresh(dialog);
+ break;
+
+ case ' ':
+ case '\r':
+ case '\n':
+ if (!button) {
+ /* A fire routine can do just about anything to the screen, so be prepared
+ to accept some hints as to what to do in the aftermath. */
+ if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int status;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ status = ditems[scroll + choice].fire(&ditems[scroll + choice]);
+ if (status & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ if (status & DITEM_CONTINUE)
+ continue;
+ else if (status & DITEM_RECREATE && !(status & DITEM_LEAVE_MENU)) {
+ delwin(menu);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ }
+ else if (result)
+ strcpy(result, items[(scroll+choice)*2]);
+ }
+ delwin(menu);
+ delwin(dialog);
+ return button;
+
+ case ESC:
+ break;
+
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ if (redraw_menu) {
+ for (i = 0; i < max_choice; i++) {
+ print_item(menu, items[(scroll + i) * 2], items[(scroll + i) * 2 + 1], i, i == choice,
+ DREF(ditems, scroll + i));
+ }
+ wnoutrefresh(menu);
+ print_arrows(dialog, scroll, menu_height, item_no, box_x, box_y, tag_x, cur_x, cur_y);
+ wrefresh(dialog);
+ redraw_menu = FALSE;
+ }
+ }
+
+ delwin(menu);
+ delwin(dialog);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_menu() */
+
+
+/*
+ * Print menu item
+ */
+static void
+print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected, dialogMenuItem *me)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < menu_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, tag_x);
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libdialog/msgbox.c b/gnu/lib/libdialog/msgbox.c
new file mode 100644
index 0000000..65e7b47
--- /dev/null
+++ b/gnu/lib/libdialog/msgbox.c
@@ -0,0 +1,342 @@
+/*
+ * msgbox.c -- implements the message box and info box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+/* local prototypes */
+static int getnlines(unsigned char *buf);
+static void print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll);
+static void print_perc(WINDOW *win, int y, int x, float p);
+
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause)
+{
+ int i, j, x, y, key = 0;
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+2*(!!pause);
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ if (pause)
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ if (pause) {
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-4, TRUE);
+ wrefresh(dialog);
+ while (key != ESC && key != '\n' && key != ' ' && key != '\r')
+ key = wgetch(dialog);
+ if (key == '\r')
+ key = '\n';
+ }
+ else {
+ key = '\n';
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (key == ESC ? -1 : 0);
+}
+/* End of dialog_msgbox() */
+
+int
+dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width)
+/*
+ * Desc: basically the same as dialog_msgbox, but ... can use PGUP, PGDN and
+ * arrowkeys to move around the text and pause is always enabled
+ */
+{
+ int i, j, x, y, key=0;
+ int theight, startline, hscroll, max_lines;
+ WINDOW *dialog;
+
+ if (height < 0)
+ height = strheight(prompt)+2+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = (COLS - width)/2;
+ y = (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-2, TRUE);
+ wattrset(dialog, dialog_attr);
+
+ theight = height - 4;
+ startline = 0;
+ hscroll = 0;
+ max_lines = getnlines(prompt);
+ print_page(dialog, theight, width, prompt, startline, hscroll);
+ print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
+ wmove(dialog, height-2, width/2-6);
+ wrefresh(dialog);
+ while ((key != ESC) && (key != '\n') && (key != '\r')) {
+ key = wgetch(dialog);
+ switch(key) {
+ case KEY_HOME:
+ startline=0;
+ hscroll=0;
+ break;
+ case KEY_END:
+ startline = max_lines - theight;
+ if (startline < 0) startline = 0;
+ break;
+ case KEY_UP:
+ if (startline > 0) startline--;
+ break;
+ case KEY_DOWN:
+ if (startline < max_lines - theight) startline++;
+ break;
+ case KEY_RIGHT:
+ hscroll+=5;
+ break;
+ case KEY_LEFT:
+ if (hscroll > 0) hscroll-=5;
+ if (hscroll < 0) hscroll =0;
+ break;
+ case KEY_PPAGE:
+ if (startline - height > 0) {
+ startline -= theight;
+ } else {
+ startline = 0;
+ }
+ break;
+ case KEY_NPAGE:
+ if (startline + theight < max_lines - theight) {
+ startline += theight;
+ } else {
+ startline = max_lines - theight;
+ if (startline < 0) startline = 0;
+ }
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ print_page(dialog, theight, width, prompt, startline, hscroll);
+ print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
+ wmove(dialog, height-2, width/2-2);
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (key == ESC ? -1 : 0);
+
+} /* dialog_mesgbox() */
+
+static void
+print_perc(WINDOW *win, int y, int x, float p)
+/*
+ * Desc: print p as a percentage at the coordinates (y,x)
+ */
+{
+ char ps[10];
+
+ if (p>1.0) p=1.0;
+ sprintf(ps, "(%3d%%)", (int) (p*100));
+ wmove(win, y, x);
+ waddstr(win, ps);
+
+ return;
+} /* print_perc() */
+
+static int
+getnlines(unsigned char *buf)
+/*
+ * Desc: count the # of lines in <buf>
+ */
+{
+ int i = 0;
+
+ if (*buf)
+ i++;
+ while (*buf) {
+ if (*buf == '\n' || *buf == '\r')
+ i++;
+ buf++;
+ }
+ return(i);
+} /* getlines() */
+
+
+unsigned char *
+getline(unsigned char *buf, int n)
+/*
+ * Desc: return a pointer to the n'th line in <buf> or NULL if its
+ * not there
+ */
+{
+ int i;
+
+ if (n<0) {
+ return(NULL);
+ }
+
+ i=0;
+ while (*buf && i<n) {
+ if (*buf == '\n' || *buf == '\r') {
+ i++;
+ }
+ buf++;
+ }
+ if (i<n) {
+ return(NULL);
+ } else {
+ return(buf);
+ }
+} /* getline() */
+
+static void
+print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll)
+/*
+ * Desc: Print a page of text in the current window, starting at line <startline>
+ * with a <horizontal> scroll of hscroll from buffer <buf>
+ */
+{
+ int i, j;
+ unsigned char *b;
+
+ b = getline(buf, startline);
+ for (i=0; i<height; i++) {
+ /* clear line */
+ wmove(win, 1+i, 1);
+ for (j=0; j<width-2; j++) waddnstr(win, " ", 1);
+ wmove(win, 1+i, 1);
+ j = 0;
+ /* scroll to the right */
+ while (*b && (*b != '\n') && (*b != '\r') && (j<hscroll)) {
+ b++;
+ j++;
+ }
+ /* print new line */
+ j = 0;
+ while (*b && (*b != '\n') && (*b != '\r') && (j<width-2)) {
+ waddnstr(win, b, 1);
+ if (*b != '\t') { /* check for tabs */
+ j++;
+ } else {
+ j = ((int) (j+1)/8 + 1) * 8 - 1;
+ }
+ b++;
+ }
+ while (*b && (*b != '\n') && (*b != '\r')) b++;
+ if (*b) b++; /* skip over '\n', if it exists */
+ }
+} /* print_page() */
+
+
+
+
diff --git a/gnu/lib/libdialog/notify.c b/gnu/lib/libdialog/notify.c
new file mode 100644
index 0000000..052ee8f
--- /dev/null
+++ b/gnu/lib/libdialog/notify.c
@@ -0,0 +1,50 @@
+/*
+ * File: notify.c
+ * Author: Marc van Kempen
+ * Desc: display a notify box with a message
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+
+#include <dialog.h>
+#include <stdio.h>
+
+void
+dialog_notify(char *msg)
+/*
+ * Desc: display an error message
+ */
+{
+ char *tmphlp;
+ WINDOW *w;
+
+ w = dupwin(newscr);
+ if (w == NULL) {
+ endwin();
+ fprintf(stderr, "\ndupwin(newscr) failed, malloc memory corrupted\n");
+ exit(1);
+ }
+ tmphlp = get_helpline();
+ use_helpline("Press enter to continue");
+ dialog_mesgbox("Message", msg, -1, -1);
+ restore_helpline(tmphlp);
+ touchwin(w);
+ wrefresh(w);
+ delwin(w);
+
+ return;
+
+} /* dialog_notify() */
+
diff --git a/gnu/lib/libdialog/prgbox.c b/gnu/lib/libdialog/prgbox.c
new file mode 100644
index 0000000..951d666
--- /dev/null
+++ b/gnu/lib/libdialog/prgbox.c
@@ -0,0 +1,148 @@
+/*
+ * prgbox.c -- implements the message box and info box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include "dialog.priv.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell)
+{
+ int i, x, y, key = 0;
+ WINDOW *dialog;
+ FILE *f;
+ const unsigned char *name;
+ unsigned char *s, buf[MAX_LEN];
+ int status;
+
+ if (height < 0 || width < 0) {
+ endwin();
+ fprintf(stderr, "\nAutosizing is impossible in dialog_prgbox().\n");
+ exit(-1);
+ }
+ width = MAX(width,10);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+
+ if (!use_shell) {
+ char cmdline[MAX_LEN];
+ char *av[51], **ap = av, *val, *p;
+
+ strcpy(cmdline, line);
+ p = cmdline;
+ while ((val = strsep(&p," \t")) != NULL) {
+ if (*val != '\0')
+ *ap++ = val;
+ }
+ *ap = NULL;
+ f = raw_popen(name = av[0], av, "r");
+ } else
+ f = raw_popen(name = line, NULL, "r");
+
+ status = -1;
+ if (f == NULL) {
+ err:
+ sprintf(buf, "%s: %s\n", name, strerror(errno));
+ prr:
+ print_autowrap(dialog, buf, height-(pause?3:1), width-2, width, 1, 2, FALSE, TRUE);
+ wrefresh(dialog);
+ } else {
+ while (fgets(buf, sizeof(buf), f) != NULL) {
+ i = strlen(buf);
+ if (buf[i-1] == '\n')
+ buf[i-1] = '\0';
+ s = buf;
+ while ((s = strchr(s, '\t')) != NULL)
+ *s++ = ' ';
+ print_autowrap(dialog, buf, height-(pause?3:1), width-2, width, 1, 2, FALSE, TRUE);
+ print_autowrap(dialog, "\n", height-(pause?3:1), width-2, width, 1, 2, FALSE, FALSE);
+ wrefresh(dialog);
+ }
+ if ((status = raw_pclose(f)) == -1)
+ goto err;
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 127) {
+ sprintf(buf, "%s: program not found\n", name);
+ goto prr;
+ }
+ }
+
+ if (pause) {
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+ display_helpline(dialog, height-1, width);
+ print_button(dialog, " OK ", height-2, width/2-4, TRUE);
+ wrefresh(dialog);
+ while (key != ESC && key != '\n' && key != ' ' && key != '\r')
+ key = wgetch(dialog);
+ if (key == '\r')
+ key = '\n';
+ }
+ else {
+ key = '\n';
+ wrefresh(dialog);
+ }
+
+ delwin(dialog);
+ return (status);
+}
+/* End of dialog_msgbox() */
diff --git a/gnu/lib/libdialog/radiolist.c b/gnu/lib/libdialog/radiolist.c
new file mode 100644
index 0000000..f0ad833
--- /dev/null
+++ b/gnu/lib/libdialog/radiolist.c
@@ -0,0 +1,533 @@
+/*
+ * radiolist.c -- implements the radiolist box
+ *
+ * AUTHOR: Stuart Herbert - S.Herbert@sheffield.ac.uk
+ * (from checklist.c by Savio Lam (lam836@cs.cuhk.hk))
+ *
+ * Substantial rennovation: 12/18/95, Jordan K. Hubbard
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+static void print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected, dialogMenuItem *me);
+
+#define DREF(di, item) ((di) ? &((di)[(item)]) : NULL)
+
+static int list_width, check_x, item_x;
+
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int
+dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height,
+ int cnt, void *it, unsigned char *result)
+{
+ int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0,
+ l, k, scroll = 0, max_choice, *status, item_no = 0, was_on = 0;
+ int redraw_menu = FALSE;
+ char okButton, cancelButton;
+ WINDOW *dialog, *list;
+ unsigned char **items = NULL;
+ dialogMenuItem *ditems;
+
+ /* Allocate space for storing item on/off status */
+ if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_radiolist().\n");
+ exit(-1);
+ }
+
+draw:
+ /* Previous calling syntax, e.g. just a list of strings? */
+ if (cnt >= 0) {
+ items = it;
+ ditems = NULL;
+ item_no = cnt;
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = !strcasecmp(items[i*3 + 2], "on");
+ if (status[i]) {
+ if (was_on)
+ status[i] = FALSE;
+ else
+ was_on = 1;
+ }
+ }
+ }
+ /* It's the new specification format - fake the rest of the code out */
+ else {
+ item_no = abs(cnt);
+ ditems = it;
+ if (!items)
+ items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
+ /* Initializes status */
+ for (i = 0; i < item_no; i++) {
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ if (status[i]) {
+ if (was_on)
+ status[i] = FALSE;
+ else
+ was_on = 1;
+ }
+ items[i*3] = ditems[i].prompt;
+ items[i*3 + 1] = ditems[i].title;
+ items[i*3 + 2] = status[i] ? "on" : "off";
+ }
+ }
+ max_choice = MIN(list_height, item_no);
+
+ check_x = 0;
+ item_x = 0;
+ /* Find length of longest item in order to center radiolist */
+ for (i = 0; i < item_no; i++) {
+ l = strlen(items[i*3]);
+ for (j = 0; j < item_no; j++) {
+ k = strlen(items[j*3 + 1]);
+ check_x = MAX(check_x, l + k + 6);
+ }
+ item_x = MAX(item_x, l);
+ }
+ if (height < 0)
+ height = strheight(prompt)+list_height+4+2;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j);
+ width = MAX(width,check_x+4)+4;
+ }
+ width = MAX(width,24);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ return -1;
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ list_width = width-6;
+ getyx(dialog, cur_y, cur_x);
+ box_y = cur_y + 1;
+ box_x = (width - list_width)/2 - 1;
+
+ /* create new window for the list */
+ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
+ if (list == NULL) {
+ delwin(dialog);
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height,list_width,y+box_y+1,x+box_x+1);
+ return -1;
+ }
+ keypad(list, TRUE);
+
+ /* draw a box around the list items */
+ draw_box(dialog, box_y, box_x, list_height+2, list_width+2, menubox_border_attr, menubox_attr);
+
+ check_x = (list_width - check_x) / 2;
+ item_x = check_x + item_x + 6;
+
+ /* Print the list */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[i*3], items[i*3 + 1], status[i], i, i == choice, DREF(ditems, i));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-11;
+ y = height-2;
+ if (ditems && result) {
+ cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
+ okButton = toupper(ditems[OK_BUTTON].prompt[0]);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
+ }
+ else {
+ cancelButton = 'C';
+ print_button(dialog, "Cancel", y, x + 14, FALSE);
+ okButton = 'O';
+ print_button(dialog, " OK ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+
+ /* See if its the short-cut to "OK" */
+ if (toupper(key) == okButton) {
+ if (ditems) {
+ if (result && ditems[OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcat(result, items[i*3]);
+ break;
+ }
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return 0;
+ }
+ /* Shortcut to cancel */
+ else if (toupper(key) == cancelButton) {
+ if (ditems && result && ditems[CANCEL_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ delwin(list);
+ delwin(dialog);
+ return 1;
+ }
+
+ /* Check if key pressed matches first character of any item tag in list */
+ for (i = 0; i < max_choice; i++)
+ if (toupper(key) == toupper(items[(scroll + i) * 3][0]))
+ break;
+
+ if (i < max_choice || (key >= '1' && key <= MIN('9', '0' + max_choice)) ||
+ key == KEY_UP || key == KEY_DOWN || key == ' ' || key == '+' || key == '-' ) {
+ if (key >= '1' && key <= MIN('9', '0' + max_choice))
+ i = key - '1';
+ else if (key == KEY_UP || key == '-') {
+ if (!choice) {
+ if (scroll) {
+ /* Scroll list down */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current first item before scrolling down */
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll));
+ scrollok(list, TRUE);
+ wscrl(list, -1);
+ scrollok(list, FALSE);
+ }
+ scroll--;
+ print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice - 1;
+ }
+ else if (key == KEY_DOWN || key == '+') {
+ if (choice == max_choice - 1) {
+ if (scroll + choice < item_no - 1) {
+ /* Scroll list up */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ if (list_height > 1) {
+ /* De-highlight current last item before scrolling up */
+ print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
+ status[scroll + max_choice - 1], max_choice - 1, FALSE, DREF(ditems, scroll + max_choice - 1));
+ scrollok(list, TRUE);
+ scroll(list);
+ scrollok(list, FALSE);
+ }
+ scroll++;
+ print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1],
+ status[scroll + max_choice - 1], max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+ else
+ i = choice + 1;
+ }
+ else if (key == ' ') { /* Toggle item status */
+ if (status[scroll + choice])
+ continue;
+ else if (ditems) {
+ if (ditems[scroll + choice].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[scroll + choice].fire(&ditems[scroll + choice]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ if (st & DITEM_REDRAW) {
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+
+ for (i = 0; i < max_choice; i++) {
+ print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
+ status[scroll + i], i, i == choice,
+ DREF(ditems, scroll + i));
+ }
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ delwin(save);
+ if (st & DITEM_LEAVE_MENU) {
+ /* Allow a fire action to take us out of the menu */
+ key = ESC;
+ break;
+ }
+ else if (st & DITEM_RECREATE) {
+ delwin(list);
+ delwin(dialog);
+ dialog_clear();
+ goto draw;
+ }
+ }
+ for (i = 0; i < item_no; i++)
+ status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
+ }
+ else {
+ for (i = 0; i < item_no; i++)
+ status[i] = 0;
+ status[scroll + choice] = TRUE;
+ }
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
+ DREF(ditems, scroll + i));
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ continue; /* wait for another key press */
+ }
+
+ if (i != choice) {
+ /* De-highlight current item */
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 +1],
+ status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice));
+ /* Highlight new item */
+ choice = i;
+ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1],
+ status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice));
+ wnoutrefresh(list);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor to previous position */
+ wrefresh(dialog);
+ }
+ continue; /* wait for another key press */
+ }
+
+ switch (key) {
+ case KEY_PPAGE:
+ if (scroll > height-4) /* can we go up? */
+ scroll -= (height-4);
+ else
+ scroll = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_NPAGE:
+ if (scroll + list_height >= item_no-1 - list_height) { /* can we go down a full page? */
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ }
+ else
+ scroll += list_height;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_HOME:
+ scroll = 0;
+ choice = 0;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_END:
+ scroll = item_no - list_height;
+ if (scroll < 0)
+ scroll = 0;
+ choice = max_choice - 1;
+ redraw_menu = TRUE;
+ break;
+
+ case KEY_BTAB:
+ case TAB:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ button = !button;
+ if (ditems && result) {
+ print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5,
+ ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
+ print_button(dialog, ditems[OK_BUTTON].prompt, y, x,
+ ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
+ }
+ else {
+ print_button(dialog, "Cancel", y, x + 14, button);
+ print_button(dialog, " OK ", y, x, !button);
+ }
+ wrefresh(dialog);
+ break;
+
+ case '\r':
+ case '\n':
+ if (ditems) {
+ if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
+ int st;
+ WINDOW *save;
+
+ save = dupwin(newscr);
+ st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
+ if (st & DITEM_RESTORE) {
+ touchwin(save);
+ wrefresh(save);
+ }
+ delwin(save);
+ }
+ }
+ else if (result) {
+ *result = '\0';
+ for (i = 0; i < item_no; i++) {
+ if (status[i]) {
+ strcpy(result, items[i*3]);
+ break;
+ }
+ }
+ }
+ delwin(list);
+ delwin(dialog);
+ return button;
+ break;
+
+ case ESC:
+ break;
+
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+
+ if (redraw_menu) {
+ for (i = 0; i < max_choice; i++)
+ print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice,
+ DREF(ditems, scroll + i));
+ wnoutrefresh(list);
+ print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
+ wrefresh(dialog);
+ redraw_menu = FALSE;
+ }
+ }
+
+ delwin(list);
+ delwin(dialog);
+ free(status);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_radiolist() */
+
+
+/*
+ * Print list item
+ */
+static void
+print_item(WINDOW *win, char *tag, char *item, int status, int choice, int selected, dialogMenuItem *me)
+{
+ int i;
+
+ /* Clear 'residue' of last item */
+ wattrset(win, menubox_attr);
+ wmove(win, choice, 0);
+ for (i = 0; i < list_width; i++)
+ waddch(win, ' ');
+ wmove(win, choice, check_x);
+ wattrset(win, selected ? check_selected_attr : check_attr);
+ wprintw(win, "%c%c%c", me && me->lbra ? me->lbra : '(',
+ status ? me && me->mark ? me->mark : '*' : ' ',
+ me && me->rbra ? me->rbra : ')');
+ wattrset(win, menubox_attr);
+ waddch(win, ' ');
+ wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+ waddch(win, tag[0]);
+ wattrset(win, selected ? tag_selected_attr : tag_attr);
+ waddstr(win, tag + 1);
+ wmove(win, choice, item_x);
+ wattrset(win, selected ? item_selected_attr : item_attr);
+ waddstr(win, item);
+ /* If have a selection handler for this, call it */
+ if (me && me->selected) {
+ wrefresh(win);
+ me->selected(me, selected);
+ }
+}
+/* End of print_item() */
diff --git a/gnu/lib/libdialog/raw_popen.c b/gnu/lib/libdialog/raw_popen.c
new file mode 100644
index 0000000..fabf91e
--- /dev/null
+++ b/gnu/lib/libdialog/raw_popen.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software written by Ken Arnold and
+ * published in UNIX Review, Vol. 6, No. 8.
+ *
+ * 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 acknowledgement:
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)popen.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <paths.h>
+
+static struct pid {
+ struct pid *next;
+ FILE *fp;
+ pid_t pid;
+} *pidlist;
+
+FILE *
+raw_popen(const char *program, char * const *argv, const char *type)
+{
+ struct pid *cur;
+ FILE *iop;
+ int pdes[2], pid;
+
+ if ((*type != 'r' && *type != 'w') || type[1])
+ return (NULL);
+
+ if ((cur = malloc(sizeof(struct pid))) == NULL)
+ return (NULL);
+
+ if (pipe(pdes) < 0) {
+ (void)free(cur);
+ return (NULL);
+ }
+
+ switch (pid = vfork()) {
+ case -1: /* Error. */
+ (void)close(pdes[0]);
+ (void)close(pdes[1]);
+ (void)free(cur);
+ return (NULL);
+ /* NOTREACHED */
+ case 0: /* Child. */
+ if (*type == 'r') {
+ if (pdes[1] != STDOUT_FILENO) {
+ (void)dup2(pdes[1], STDOUT_FILENO);
+ (void)close(pdes[1]);
+ }
+ (void) close(pdes[0]);
+ } else {
+ if (pdes[0] != STDIN_FILENO) {
+ (void)dup2(pdes[0], STDIN_FILENO);
+ (void)close(pdes[0]);
+ }
+ (void)close(pdes[1]);
+ }
+ if (argv == NULL)
+ execl(_PATH_BSHELL, "sh", "-c", program, NULL);
+ else
+ execvp(program, argv);
+ _exit(127);
+ /* NOTREACHED */
+ }
+
+ /* Parent; assume fdopen can't fail. */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ (void)close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ (void)close(pdes[0]);
+ }
+
+ /* Link into list of file descriptors. */
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
+
+ return (iop);
+}
+
+/*
+ * pclose --
+ * Pclose returns -1 if stream is not associated with a `popened' command,
+ * if already `pclosed', or waitpid returns an error.
+ */
+int
+raw_pclose(FILE *iop)
+{
+ register struct pid *cur, *last;
+ int omask;
+ union wait pstat;
+ pid_t pid;
+
+ (void)fclose(iop);
+
+ /* Find the appropriate file pointer. */
+ for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
+ if (cur->fp == iop)
+ break;
+ if (cur == NULL)
+ return (-1);
+
+ /* Get the status of the process. */
+ omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
+ do {
+ pid = waitpid(cur->pid, (int *) &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+ (void)sigsetmask(omask);
+
+ /* Remove the entry from the linked list. */
+ if (last == NULL)
+ pidlist = cur->next;
+ else
+ last->next = cur->next;
+ free(cur);
+
+ return (pid == -1 ? -1 : pstat.w_status);
+}
diff --git a/gnu/lib/libdialog/rc.c b/gnu/lib/libdialog/rc.c
new file mode 100644
index 0000000..36631a6
--- /dev/null
+++ b/gnu/lib/libdialog/rc.c
@@ -0,0 +1,375 @@
+/*
+ * rc.c -- routines for processing the configuration file
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <dialog.h>
+#include "dialog.priv.h"
+#include "colors.h"
+#include "rc.h"
+
+
+static unsigned char *attr_to_str(int fg, int bg, int hl);
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl);
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value);
+
+
+/*
+ * Create the configuration file
+ */
+void dialog_create_rc(unsigned char *filename)
+{
+ int i;
+ FILE *rc_file;
+
+ if ((rc_file = fopen(filename, "wt")) == NULL) {
+ fprintf(stderr, "\nError opening file for writing in create_rc().\n");
+ exit(-1);
+ }
+
+ fprintf(rc_file, "#\
+\n# Run-time configuration file for dialog\
+\n#\
+\n# Automatically generated by \"dialog --create-rc <file>\"\
+\n#\
+\n#\
+\n# Types of values:\
+\n#\
+\n# Number - <number>\
+\n# String - \"string\"\
+\n# Boolean - <ON|OFF>\
+\n# Attribute - (foreground,background,highlight?)\
+\n#\n\n");
+
+ /* Print an entry for each configuration variable */
+ for (i = 0; i < VAR_COUNT; i++) {
+ fprintf(rc_file, "\n# %s\n", vars[i].comment); /* print comment */
+ switch (vars[i].type) {
+ case VAL_INT:
+ fprintf(rc_file, "%s = %d\n", vars[i].name, *((int *) vars[i].var));
+ break;
+ case VAL_STR:
+ fprintf(rc_file, "%s = \"%s\"\n", vars[i].name, (unsigned char *) vars[i].var);
+ break;
+ case VAL_BOOL:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, *((bool *) vars[i].var) ? "ON" : "OFF");
+ break;
+ case VAL_ATTR:
+ fprintf(rc_file, "%s = %s\n", vars[i].name, attr_to_str(((int *) vars[i].var)[0], ((int *) vars[i].var)[1], ((int *) vars[i].var)[2]));
+ break;
+ }
+ }
+
+ fclose(rc_file);
+}
+/* End of create_rc() */
+
+
+/*
+ * Parse the configuration file and set up variables
+ */
+int parse_rc(void)
+{
+ int i, l = 1, parse, fg, bg, hl;
+ unsigned char str[MAX_LEN+1], *var, *value, *tempptr;
+ FILE *rc_file;
+
+ /*
+ *
+ * At start, 'dialog' determines the settings to use as follows:
+ *
+ * a) if environment variable DIALOGRC is set, it's value determines the
+ * name of the configuration file.
+ *
+ * b) if the file in (a) can't be found, use the file $HOME/.dialogrc
+ * as the configuration file.
+ *
+ * c) if the file in (b) can't be found, use compiled in defaults.
+ *
+ */
+
+ if ((tempptr = getenv("DIALOGRC")) != NULL)
+ rc_file = fopen(tempptr, "rt");
+
+ if (tempptr == NULL || rc_file == NULL) { /* step (a) failed? */
+ /* try step (b) */
+ if ((tempptr = getenv("HOME")) == NULL)
+ return 0; /* step (b) failed, use default values */
+
+ if (tempptr[0] == '\0' || lastch(tempptr) == '/')
+ sprintf(str, "%s%s", tempptr, DIALOGRC);
+ else
+ sprintf(str, "%s/%s", tempptr, DIALOGRC);
+
+ if ((rc_file = fopen(str, "rt")) == NULL)
+ return 0; /* step (b) failed, use default values */
+ }
+
+ /* Scan each line and set variables */
+ while (fgets(str, MAX_LEN, rc_file) != NULL) {
+ if (lastch(str) != '\n') { /* ignore rest of file if line too long */
+ fprintf(stderr, "\nParse error: line %d of configuration file too long.\n", l);
+ fclose(rc_file);
+ return -1; /* parse aborted */
+ }
+ else {
+ lastch(str) = '\0';
+ parse = parse_line(str, &var, &value); /* parse current line */
+
+ switch (parse) {
+ case LINE_BLANK: /* ignore blank lines and comments */
+ case LINE_COMMENT:
+ break;
+ case LINE_OK:
+ /* search table for matching config variable name */
+ for (i = 0; i < VAR_COUNT && strcmp(vars[i].name, var); i++);
+
+ if (i == VAR_COUNT) { /* no match */
+ fprintf(stderr, "\nParse error: unknown variable at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else { /* variable found in table, set run time variables */
+ switch (vars[i].type) {
+ case VAL_INT:
+ *((int *) vars[i].var) = atoi(value);
+ break;
+ case VAL_STR:
+ if (!isquote(value[0]) || !isquote(lastch(value)) || strlen(value) < 2) {
+ fprintf(stderr, "\nParse error: string value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ else {
+ /* remove the (") quotes */
+ value++;
+ lastch(value) = '\0';
+ strcpy((unsigned char *) vars[i].var, value);
+ }
+ break;
+ case VAL_BOOL:
+ if (!strcasecmp(value, "ON"))
+ *((bool *) vars[i].var) = TRUE;
+ else if (!strcasecmp(value, "OFF"))
+ *((bool *) vars[i].var) = FALSE;
+ else {
+ fprintf(stderr, "\nParse error: boolean value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ break;
+ case VAL_ATTR:
+ if (str_to_attr(value, &fg, &bg, &hl) == -1) {
+ fprintf(stderr, "\nParse error: attribute value expected at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ ((int *) vars[i].var)[0] = fg;
+ ((int *) vars[i].var)[1] = bg;
+ ((int *) vars[i].var)[2] = hl;
+ break;
+ }
+ }
+ break;
+ case LINE_ERROR:
+ fprintf(stderr, "\nParse error: syntax error at line %d of configuration file.\n", l);
+ return -1; /* parse aborted */
+ }
+ }
+
+ l++; /* next line */
+ }
+
+ fclose(rc_file);
+ return 0; /* parse successful */
+}
+/* End of parse_rc() */
+
+
+/*
+ * Convert an attribute to a string representation like this:
+ *
+ * "(foreground,background,highlight)"
+ */
+static unsigned char *attr_to_str(int fg, int bg, int hl)
+{
+ int i;
+ static unsigned char str[MAX_LEN+1];
+
+ strcpy(str, "(");
+ /* foreground */
+ for (i = 0; fg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+ strcat(str, ",");
+
+ /* background */
+ for (i = 0; bg != color_names[i].value; i++);
+ strcat(str, color_names[i].name);
+
+ /* highlight */
+ strcat(str, hl ? ",ON)" : ",OFF)");
+
+ return str;
+}
+/* End of attr_to_str() */
+
+
+/*
+ * Extract the foreground, background and highlight values from an attribute
+ * represented as a string in this form:
+ *
+ * "(foreground,background,highlight)"
+ */
+static int str_to_attr(unsigned char *str, int *fg, int *bg, int *hl)
+{
+ int i = 0, j, get_fg = 1;
+ unsigned char tempstr[MAX_LEN+1], *part;
+
+ if (str[0] != '(' || lastch(str) != ')')
+ return -1; /* invalid representation */
+
+ /* remove the parenthesis */
+ strcpy(tempstr, str + 1);
+ lastch(tempstr) = '\0';
+
+
+ /* get foreground and background */
+
+ while (1) {
+ /* skip white space before fg/bg string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of fg/bg string */
+
+ /* find end of fg/bg string */
+ while(!whitespace(tempstr[i]) && tempstr[i] != ',' && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ else if (whitespace(tempstr[i])) { /* not yet ',' */
+ tempstr[i++] = '\0';
+
+ /* skip white space before ',' */
+ while(whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+
+ if (tempstr[i] != ',')
+ return -1; /* invalid representation */
+ }
+
+ tempstr[i++] = '\0'; /* skip the ',' */
+ for (j = 0; j < COLOR_COUNT && strcasecmp(part, color_names[j].name); j++);
+ if (j == COLOR_COUNT) /* invalid color name */
+ return -1;
+ if (get_fg) {
+ *fg = color_names[j].value;
+ get_fg = 0; /* next we have to get the background */
+ }
+ else {
+ *bg = color_names[j].value;
+ break;
+ }
+ } /* got foreground and background */
+
+
+ /* get highlight */
+
+ /* skip white space before highlight string */
+ while (whitespace(tempstr[i]) && tempstr[i] != '\0') i++;
+ if (tempstr[i] == '\0')
+ return -1; /* invalid representation */
+ part = tempstr + i; /* set 'part' to start of highlight string */
+
+ /* trim trailing white space from highlight string */
+ i = strlen(part) - 1;
+ while(whitespace(part[i])) i--;
+ part[i+1] = '\0';
+
+ if (!strcasecmp(part, "ON"))
+ *hl = TRUE;
+ else if (!strcasecmp(part, "OFF"))
+ *hl = FALSE;
+ else
+ return -1; /* invalid highlight value */
+
+ return 0;
+}
+/* End of str_to_attr() */
+
+
+/*
+ * Parse a line in the configuration file
+ *
+ * Each line is of the form: "variable = value". On exit, 'var' will contain
+ * the variable name, and 'value' will contain the value string.
+ *
+ * Return values:
+ *
+ * LINE_BLANK - line is blank
+ * LINE_COMMENT - line is comment
+ * LINE_OK - line is ok
+ * LINE_ERROR - syntax error in line
+ */
+static int parse_line(unsigned char *line, unsigned char **var, unsigned char **value)
+{
+ int i = 0;
+
+ /* ignore white space at beginning of line */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* line is blank */
+ return LINE_BLANK;
+ else if (line[i] == '#') /* line is comment */
+ return LINE_COMMENT;
+ else if (line[i] == '=') /* variables names can't strart with a '=' */
+ return LINE_ERROR;
+
+ /* set 'var' to variable name */
+ *var = line + i++; /* skip to next character */
+
+ /* find end of variable name */
+ while(!whitespace(line[i]) && line[i] != '=' && line[i] != '\0') i++;
+
+ if (line[i] == '\0') /* syntax error */
+ return LINE_ERROR;
+ else if (line[i] == '=')
+ line[i++] = '\0';
+ else {
+ line[i++] = '\0';
+
+ /* skip white space before '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] != '=') /* syntax error */
+ return LINE_ERROR;
+ else
+ i++; /* skip the '=' */
+ }
+
+ /* skip white space after '=' */
+ while(whitespace(line[i]) && line[i] != '\0') i++;
+
+ if (line[i] == '\0')
+ return LINE_ERROR;
+ else
+ *value = line + i; /* set 'value' to value string */
+
+ /* trim trailing white space from 'value' */
+ i = strlen(*value) - 1;
+ while(whitespace((*value)[i])) i--;
+ (*value)[i+1] = '\0';
+
+ return LINE_OK; /* no syntax error in line */
+}
+/* End of parse_line() */
diff --git a/gnu/lib/libdialog/rc.h b/gnu/lib/libdialog/rc.h
new file mode 100644
index 0000000..fc19d03
--- /dev/null
+++ b/gnu/lib/libdialog/rc.h
@@ -0,0 +1,222 @@
+/*
+ * rc.h -- declarations for configuration file processing
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#define DIALOGRC ".dialogrc"
+#define VAR_LEN 30
+#define COMMENT_LEN 70
+
+/* Types of values */
+#define VAL_INT 0
+#define VAL_STR 1
+#define VAL_BOOL 2
+#define VAL_ATTR 3
+
+/* Type of line in configuration file */
+#define LINE_BLANK 2
+#define LINE_COMMENT 1
+#define LINE_OK 0
+#define LINE_ERROR -1
+
+/* number of configuration variables */
+#define VAR_COUNT (sizeof(vars) / sizeof(vars_st))
+
+/* check if character is white space */
+#define whitespace(c) (c == ' ' || c == '\t')
+
+/* check if character is string quoting characters */
+#define isquote(c) (c == '"' || c == '\'')
+
+/* get last character of string */
+#define lastch(str) str[strlen(str)-1]
+
+/*
+ * Configuration variables
+ */
+typedef struct {
+ unsigned char name[VAR_LEN]; /* name of configuration variable as in DIALOGRC */
+ void *var; /* address of actually variable to change */
+ int type; /* type of value */
+ unsigned char comment[COMMENT_LEN]; /* comment to put in "rc" file */
+} vars_st;
+
+vars_st vars[] = {
+ { "use_shadow",
+ &use_shadow,
+ VAL_BOOL,
+ "Shadow dialog boxes? This also turns on color." },
+
+ { "use_colors",
+ &use_colors,
+ VAL_BOOL,
+ "Turn color support ON or OFF" },
+
+ { "screen_color",
+ color_table[0],
+ VAL_ATTR,
+ "Screen color" },
+
+ { "shadow_color",
+ color_table[1],
+ VAL_ATTR,
+ "Shadow color" },
+
+ { "dialog_color",
+ color_table[2],
+ VAL_ATTR,
+ "Dialog box color" },
+
+ { "title_color",
+ color_table[3],
+ VAL_ATTR,
+ "Dialog box title color" },
+
+ { "border_color",
+ color_table[4],
+ VAL_ATTR,
+ "Dialog box border color" },
+
+ { "button_active_color",
+ color_table[5],
+ VAL_ATTR,
+ "Active button color" },
+
+ { "button_inactive_color",
+ color_table[6],
+ VAL_ATTR,
+ "Inactive button color" },
+
+ { "button_key_active_color",
+ color_table[7],
+ VAL_ATTR,
+ "Active button key color" },
+
+ { "button_key_inactive_color",
+ color_table[8],
+ VAL_ATTR,
+ "Inactive button key color" },
+
+ { "button_label_active_color",
+ color_table[9],
+ VAL_ATTR,
+ "Active button label color" },
+
+ { "button_label_inactive_color",
+ color_table[10],
+ VAL_ATTR,
+ "Inactive button label color" },
+
+ { "inputbox_color",
+ color_table[11],
+ VAL_ATTR,
+ "Input box color" },
+
+ { "inputbox_border_color",
+ color_table[12],
+ VAL_ATTR,
+ "Input box border color" },
+
+ { "searchbox_color",
+ color_table[13],
+ VAL_ATTR,
+ "Search box color" },
+
+ { "searchbox_title_color",
+ color_table[14],
+ VAL_ATTR,
+ "Search box title color" },
+
+ { "searchbox_border_color",
+ color_table[15],
+ VAL_ATTR,
+ "Search box border color" },
+
+ { "position_indicator_color",
+ color_table[16],
+ VAL_ATTR,
+ "File position indicator color" },
+
+ { "menubox_color",
+ color_table[17],
+ VAL_ATTR,
+ "Menu box color" },
+
+ { "menubox_border_color",
+ color_table[18],
+ VAL_ATTR,
+ "Menu box border color" },
+
+ { "item_color",
+ color_table[19],
+ VAL_ATTR,
+ "Item color" },
+
+ { "item_selected_color",
+ color_table[20],
+ VAL_ATTR,
+ "Selected item color" },
+
+ { "tag_color",
+ color_table[21],
+ VAL_ATTR,
+ "Tag color" },
+
+ { "tag_selected_color",
+ color_table[22],
+ VAL_ATTR,
+ "Selected tag color" },
+
+ { "tag_key_color",
+ color_table[23],
+ VAL_ATTR,
+ "Tag key color" },
+
+ { "tag_key_selected_color",
+ color_table[24],
+ VAL_ATTR,
+ "Selected tag key color" },
+
+ { "check_color",
+ color_table[25],
+ VAL_ATTR,
+ "Check box color" },
+
+ { "check_selected_color",
+ color_table[26],
+ VAL_ATTR,
+ "Selected check box color" },
+
+ { "uarrow_color",
+ color_table[27],
+ VAL_ATTR,
+ "Up arrow color" },
+
+ { "darrow_color",
+ color_table[28],
+ VAL_ATTR,
+ "Down arrow color" }
+}; /* vars */
+
+
+
+/*
+ * Routines to process configuration file
+ */
+int parse_rc(void);
diff --git a/gnu/lib/libdialog/textbox.c b/gnu/lib/libdialog/textbox.c
new file mode 100644
index 0000000..a26247b
--- /dev/null
+++ b/gnu/lib/libdialog/textbox.c
@@ -0,0 +1,694 @@
+/*
+ * textbox.c -- implements the text box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+static void back_lines(int n);
+static void print_page(WINDOW *win, int height, int width);
+static void print_line(WINDOW *win, int row, int width);
+static unsigned char *get_line(void);
+static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width);
+static void print_position(WINDOW *win, int height, int width);
+
+
+static int hscroll = 0, fd, file_size, bytes_read, begin_reached = 1,
+ end_reached = 0, page_length;
+static unsigned char *buf, *page;
+
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
+{
+ int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
+#ifdef HAVE_NCURSES
+ int passed_end;
+#endif
+ unsigned char search_term[MAX_LEN+1], *tempptr, *found;
+ WINDOW *dialog, *text;
+
+ if (height < 0 || width < 0) {
+ fprintf(stderr, "\nAutosizing is impossible in dialog_textbox().\n");
+ return(-1);
+ }
+
+ search_term[0] = '\0'; /* no search term entered yet */
+
+ /* Open input file for reading */
+ if ((fd = open(file, O_RDONLY)) == -1) {
+ fprintf(stderr, "\nCan't open input file <%s>in dialog_textbox().\n", file);
+ return(-1);
+ }
+ /* Get file size. Actually, 'file_size' is the real file size - 1,
+ since it's only the last byte offset from the beginning */
+ if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
+ fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
+ return(-1);
+ }
+ /* Restore file pointer to beginning of file after getting file size */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ return(-1);
+ }
+ /* Allocate space for read buffer */
+ if ((buf = malloc(BUF_SIZE+1)) == NULL) {
+ endwin();
+ fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ return(-1);
+ }
+ buf[bytes_read] = '\0'; /* mark end of valid data */
+ page = buf; /* page is pointer to start of page to be displayed */
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ /* Create window for text region, used for scrolling text */
+/* text = newwin(height-4, width-2, y+1, x+1); */
+ text = subwin(dialog, height-4, width-2, y+1, x+1);
+ if (text == NULL) {
+ endwin();
+ fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", height-4,width-2,y+1,x+1);
+ exit(1);
+ }
+ keypad(text, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ display_helpline(dialog, height-1, width);
+
+ print_button(dialog, " OK ", height-2, width/2-2, TRUE);
+ wnoutrefresh(dialog);
+ getyx(dialog, cur_y, cur_x); /* Save cursor position */
+
+ /* Print first page of text */
+ attr_clear(text, height-4, width-2, dialog_attr);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+
+ while ((key != ESC) && (key != '\n') && (key != '\r')) {
+ key = wgetch(dialog);
+ switch (key) {
+ case 'E': /* Exit */
+ case 'e':
+ delwin(dialog);
+ free(buf);
+ close(fd);
+ return 0;
+ case 'g': /* First page */
+ case KEY_HOME:
+ if (!begin_reached) {
+ begin_reached = 1;
+ /* First page not in buffer? */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) { /* Yes, we have to read it in */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf;
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'G': /* Last page */
+#ifdef HAVE_NCURSES
+ case KEY_END:
+#endif
+ end_reached = 1;
+ /* Last page not in buffer? */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if (fpos < file_size) { /* Yes, we have to read it in */
+ if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ page = buf + bytes_read;
+ back_lines(height-4);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ break;
+ case 'K': /* Previous line */
+ case 'k':
+ case KEY_UP:
+ if (!begin_reached) {
+ back_lines(page_length+1);
+#ifdef HAVE_NCURSES
+ /* We don't call print_page() here but use scrolling to ensure
+ faster screen update. However, 'end_reached' and 'page_length'
+ should still be updated, and 'page' should point to start of
+ next page. This is done by calling get_line() in the following
+ 'for' loop. */
+ scrollok(text, TRUE);
+ wscrl(text, -1); /* Scroll text region down one line */
+ scrollok(text, FALSE);
+ page_length = 0;
+ passed_end = 0;
+ for (i = 0; i < height-4; i++) {
+ if (!i) {
+ print_line(text, 0, width-2); /* print first line of page */
+ wnoutrefresh(text);
+ }
+ else
+ get_line(); /* Called to update 'end_reached' and 'page' */
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+#else
+ print_page(text, height-4, width-2);
+#endif
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'B': /* Previous page */
+ case 'b':
+ case KEY_PPAGE:
+ if (!begin_reached) {
+ back_lines(page_length + height-4);
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'J': /* Next line */
+ case 'j':
+ case KEY_DOWN:
+ if (!end_reached) {
+ begin_reached = 0;
+ scrollok(text, TRUE);
+ scroll(text); /* Scroll text region up one line */
+ scrollok(text, FALSE);
+ print_line(text, height-5, width-2);
+#ifndef HAVE_NCURSES
+ wmove(text, height-5, 0);
+ waddch(text, ' ');
+ wmove(text, height-5, width-3);
+ waddch(text, ' ');
+#endif
+ wnoutrefresh(text);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case ' ': /* Next page */
+ case KEY_NPAGE:
+ if (!end_reached) {
+ begin_reached = 0;
+ print_page(text, height-4, width-2);
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case '0': /* Beginning of line */
+ case 'H': /* Scroll left */
+ case 'h':
+ case KEY_LEFT:
+ if (hscroll > 0) {
+ if (key == '0')
+ hscroll = 0;
+ else
+ hscroll--;
+ /* Reprint current page to scroll horizontally */
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case 'L': /* Scroll right */
+ case 'l':
+ case KEY_RIGHT:
+ if (hscroll < MAX_LEN) {
+ hscroll++;
+ /* Reprint current page to scroll horizontally */
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ break;
+ case '/': /* Forward search */
+ case 'n': /* Repeat forward search */
+ case '?': /* Backward search */
+ case 'N': /* Repeat backward search */
+ /* set search direction */
+ dir = (key == '/' || key == 'n') ? 1 : 0;
+ if (dir ? !end_reached : !begin_reached) {
+ if (key == 'n' || key == 'N') {
+ if (search_term[0] == '\0') { /* No search term yet */
+ fprintf(stderr, "\a"); /* beep */
+ break;
+ }
+ }
+ else /* Get search term from user */
+ if (get_search_term(text, search_term, height-4, width-2) == -1) {
+ /* ESC pressed in get_search_term(). Reprint page to clear box */
+ wattrset(text, dialog_attr);
+ back_lines(page_length);
+ print_page(text, height-4, width-2);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ break;
+ }
+ /* Save variables for restoring in case search term can't be found */
+ tempptr = page;
+ temp = begin_reached;
+ temp1 = end_reached;
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ fpos -= bytes_read;
+ /* update 'page' to point to next (previous) line before
+ forward (backward) searching */
+ back_lines(dir ? page_length-1 : page_length+1);
+ found = NULL;
+ if (dir) /* Forward search */
+ while((found = strstr(get_line(), search_term)) == NULL) {
+ if (end_reached)
+ break;
+ }
+ else /* Backward search */
+ while((found = strstr(get_line(), search_term)) == NULL) {
+ if (begin_reached)
+ break;
+ back_lines(2);
+ }
+ if (found == NULL) { /* not found */
+ fprintf(stderr, "\a"); /* beep */
+ /* Restore program state to that before searching */
+ if (lseek(fd, fpos, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+ exit(-1);
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ page = tempptr;
+ begin_reached = temp;
+ end_reached = temp1;
+ /* move 'page' to point to start of current page in order to
+ re-print current page. Note that 'page' always points to
+ start of next page, so this is necessary */
+ back_lines(page_length);
+ }
+ else /* Search term found */
+ back_lines(1);
+ /* Reprint page */
+ wattrset(text, dialog_attr);
+ print_page(text, height-4, width-2);
+ if (found != NULL)
+ print_position(dialog, height, width);
+ wmove(dialog, cur_y, cur_x); /* Restore cursor position */
+ wrefresh(dialog);
+ }
+ else /* no need to find */
+ fprintf(stderr, "\a"); /* beep */
+ break;
+ case ESC:
+ break;
+ case KEY_F(1):
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ free(buf);
+ close(fd);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_textbox() */
+
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void back_lines(int n)
+{
+ int i, fpos;
+
+ begin_reached = 0;
+ /* We have to distinguish between end_reached and !end_reached since at end
+ of file, the line is not ended by a '\n'. The code inside 'if' basically
+ does a '--page' to move one character backward so as to skip '\n' of the
+ previous line */
+ if (!end_reached) {
+ /* Either beginning of buffer or beginning of file reached? */
+ if (page == buf) {
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) { /* Not beginning of file yet */
+ /* We've reached beginning of buffer, but not beginning of file yet,
+ so read previous part of file into buffer. Note that we only
+ move backward for BUF_SIZE/2 bytes, but not BUF_SIZE bytes to
+ avoid re-reading again in print_page() later */
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE/2 + bytes_read) {
+ /* No, move less then */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + fpos - bytes_read;
+ }
+ else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + BUF_SIZE/2;
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in back_lines().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ if (*(--page) != '\n') { /* '--page' here */
+ /* Something's wrong... */
+ endwin();
+ fprintf(stderr, "\nInternal error in back_lines().\n");
+ exit(-1);
+ }
+ }
+
+ /* Go back 'n' lines */
+ for (i = 0; i < n; i++)
+ do {
+ if (page == buf) {
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ if (fpos > bytes_read) {
+ /* Really possible to move backward BUF_SIZE/2 bytes? */
+ if (fpos < BUF_SIZE/2 + bytes_read) {
+ /* No, move less then */
+ if (lseek(fd, 0, SEEK_SET) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + fpos - bytes_read;
+ }
+ else { /* Move backward BUF_SIZE/2 bytes */
+ if (lseek(fd, -(BUF_SIZE/2 + bytes_read), SEEK_CUR) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+ exit(-1);
+ }
+ page = buf + BUF_SIZE/2;
+ }
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in back_lines().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ }
+ else { /* Beginning of file reached */
+ begin_reached = 1;
+ return;
+ }
+ }
+ } while (*(--page) != '\n');
+ page++;
+}
+/* End of back_lines() */
+
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void print_page(WINDOW *win, int height, int width)
+{
+ int i, passed_end = 0;
+
+ page_length = 0;
+ for (i = 0; i < height; i++) {
+ print_line(win, i, width);
+ if (!passed_end)
+ page_length++;
+ if (end_reached && !passed_end)
+ passed_end = 1;
+ }
+ wnoutrefresh(win);
+}
+/* End of print_page() */
+
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void print_line(WINDOW *win, int row, int width)
+{
+ int i, y, x;
+ unsigned char *line;
+
+ line = get_line();
+ line += MIN(strlen(line),hscroll); /* Scroll horizontally */
+ wmove(win, row, 0); /* move cursor to correct line */
+ waddch(win,' ');
+#ifdef HAVE_NCURSES
+ waddnstr(win, line, MIN(strlen(line),width-2));
+#else
+ line[MIN(strlen(line),width-2)] = '\0';
+ waddstr(win, line);
+#endif
+
+ getyx(win, y, x);
+ /* Clear 'residue' of previous line */
+ for (i = 0; i < width-x; i++)
+ waddch(win, ' ');
+}
+/* End of print_line() */
+
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static unsigned char *get_line(void)
+{
+ int i = 0, fpos;
+ static unsigned char line[MAX_LEN+1];
+
+ end_reached = 0;
+ while (*page != '\n') {
+ if (*page == '\0') { /* Either end of file or end of buffer reached */
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in get_line().\n");
+ exit(-1);
+ }
+ if (fpos < file_size) { /* Not end of file yet */
+ /* We've reached end of buffer, but not end of file yet, so read next
+ part of file into buffer */
+ if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError reading file in get_line().\n");
+ exit(-1);
+ }
+ buf[bytes_read] = '\0';
+ page = buf;
+ }
+ else {
+ if (!end_reached)
+ end_reached = 1;
+ break;
+ }
+ }
+ else
+ if (i < MAX_LEN)
+ line[i++] = *(page++);
+ else {
+ if (i == MAX_LEN) /* Truncate lines longer than MAX_LEN characters */
+ line[i++] = '\0';
+ page++;
+ }
+ }
+ if (i <= MAX_LEN)
+ line[i] = '\0';
+ if (!end_reached)
+ page++; /* move pass '\n' */
+
+ return line;
+}
+/* End of get_line() */
+
+
+/*
+ * Display a dialog box and get the search term from user
+ */
+static int get_search_term(WINDOW *win, unsigned char *search_term, int height, int width)
+{
+ int x, y, key = 0, first,
+ box_height = 3, box_width = 30;
+
+ x = (width - box_width)/2;
+ y = (height - box_height)/2;
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(win, y, x, box_height, box_width);
+#endif
+ draw_box(win, y, x, box_height, box_width, dialog_attr, searchbox_border_attr);
+ wattrset(win, searchbox_title_attr);
+ wmove(win, y, x+box_width/2-4);
+ waddstr(win, " Search ");
+ wattrset(win, dialog_attr);
+
+ search_term[0] = '\0';
+
+ first = 1;
+ while (key != ESC) {
+ key = line_edit(win, y+1, x+1, -1, box_width-2, searchbox_attr, first, search_term);
+ first = 0;
+ switch (key) {
+ case '\n':
+ if (search_term[0] != '\0')
+ return 0;
+ break;
+ case ESC:
+ break;
+ }
+ }
+
+ return -1; /* ESC pressed */
+}
+/* End of get_search_term() */
+
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW *win, int height, int width)
+{
+ int fpos, percent;
+
+ if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+ endwin();
+ fprintf(stderr, "\nError moving file pointer in print_position().\n");
+ exit(-1);
+ }
+ wattrset(win, position_indicator_attr);
+ percent = !file_size ? 100 : ((fpos-bytes_read+page-buf)*100)/file_size;
+ wmove(win, height-3, width-9);
+ wprintw(win, "(%3d%%)", percent);
+}
+/* End of print_position() */
diff --git a/gnu/lib/libdialog/ui_objects.c b/gnu/lib/libdialog/ui_objects.c
new file mode 100644
index 0000000..e1ef014
--- /dev/null
+++ b/gnu/lib/libdialog/ui_objects.c
@@ -0,0 +1,812 @@
+/*
+ * Program: objects.c
+ * Author: Marc van Kempen
+ * Desc: Implementation of UI-objects:
+ * - String input fields
+ * - List selection
+ * - Buttons
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include <stdlib.h>
+#include <sys/param.h>
+#include <ncurses.h>
+#include <dialog.h>
+#include "dialog.priv.h"
+#include "ui_objects.h"
+
+#define ESC 27
+
+
+/***********************************************************************
+ *
+ * Obj routines
+ *
+ ***********************************************************************/
+
+void
+AddObj(ComposeObj **Obj, int objtype, void *obj)
+/*
+ * Desc: Add the object <obj> to the list of objects <Obj>
+ */
+{
+ if (*Obj == NULL) {
+ /* Create the root object */
+ *Obj = (ComposeObj *) malloc( sizeof(ComposeObj) );
+ if (!Obj) {
+ printf("AddObj: Error malloc'ing ComposeObj\n");
+ exit(-1);
+ }
+ (*Obj)->objtype = objtype;
+ (*Obj)->obj = obj;
+ (*Obj)->next = NULL;
+ (*Obj)->prev = NULL;
+ } else {
+ ComposeObj *o = *Obj;
+
+ /* create the next object */
+ while (o->next) o = (ComposeObj *) o->next;
+ o->next = (struct ComposeObj *) malloc( sizeof(ComposeObj) );
+ if (!o->next) {
+ printf("AddObj: Error malloc'ing o->next\n");
+ exit(-1);
+ }
+ o->next->objtype = objtype;
+ o->next->obj = obj;
+ o->next->next = NULL;
+ o->next->prev = o;
+ }
+
+ return;
+} /* AddObj() */
+
+void
+FreeObj(ComposeObj *Obj)
+/*
+ * Desc: free the memory occupied by *Obj
+ */
+{
+ ComposeObj *o = Obj;
+
+ o = Obj;
+ while (o) {
+ o = Obj->next;
+ free(Obj);
+ Obj = o;
+ }
+
+ return;
+} /* FreeObj() */
+
+
+int
+ReadObj(ComposeObj *Obj)
+/*
+ * Desc: navigate through the different objects calling their
+ * respective navigation routines as necessary
+ * Pre: Obj != NULL
+ */
+{
+ ComposeObj *o;
+ ComposeObj *last; /* the last object in the list */
+ int ret; /* the return value from the selection routine */
+
+ /* find the last object in the list */
+ last = Obj;
+ while (last->next) last = last->next;
+
+ ret = 0;
+ o = Obj;
+ while ((ret != SEL_BUTTON) && (ret != SEL_ESC)) {
+ switch(o->objtype) {
+ case STRINGOBJ:
+ ret = SelectStringObj((StringObj *) o->obj);
+ break;
+ case LISTOBJ:
+ ret = SelectListObj((ListObj *) o->obj);
+ break;
+ case BUTTONOBJ:
+ ret = SelectButtonObj((ButtonObj *) o->obj);
+ break;
+ }
+ switch(ret) {
+ case KEY_DOWN:
+ case SEL_CR:
+ case SEL_TAB: /* move to the next object in the list */
+ if (o->next != NULL) {
+ o = o->next; /* next object */
+ } else {
+ o = Obj; /* beginning of the list */
+ }
+ break;
+
+ case KEY_UP:
+ case SEL_BACKTAB: /* move to the previous object in the list */
+ if (o->prev != NULL) {
+ o = o->prev; /* previous object */
+ } else {
+ o = last; /* end of the list */
+ }
+ break;
+
+ case KEY_F(1): /* display help_file */
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ return(ret);
+
+} /* ReadObj() */
+
+
+int
+PollObj(ComposeObj **Obj)
+{
+ ComposeObj *last; /* the last object in the list */
+ ComposeObj *first; /* the first object in the list */
+ int ret; /* the return value from the selection routine */
+
+ /* find the last object in the list */
+ last = *Obj;
+ while (last->next) last = last->next;
+
+ /* find the first object in the list */
+ first = *Obj;
+ while (first->prev) first = first->prev;
+
+ ret = 0;
+ switch((*Obj)->objtype) {
+ case STRINGOBJ:
+ ret = SelectStringObj((StringObj *) (*Obj)->obj);
+ break;
+ case LISTOBJ:
+ ret = SelectListObj((ListObj *) (*Obj)->obj);
+ break;
+ case BUTTONOBJ:
+ ret = SelectButtonObj((ButtonObj *) (*Obj)->obj);
+ break;
+ }
+ switch(ret) {
+ case KEY_DOWN:
+ case SEL_CR:
+ case SEL_TAB: /* move to the next object in the list */
+ if ((*Obj)->next != NULL) {
+ *Obj = (*Obj)->next; /* next object */
+ } else {
+ *Obj = first; /* beginning of the list */
+ }
+ break;
+
+ case KEY_UP:
+ case SEL_BACKTAB: /* move to the previous object in the list */
+ if ((*Obj)->prev != NULL) {
+ *Obj = (*Obj)->prev; /* previous object */
+ } else {
+ *Obj = last; /* end of the list */
+ }
+ break;
+ }
+
+ return(ret);
+
+} /* PollObj() */
+
+
+void
+DelObj(ComposeObj *Obj)
+/*
+ * Desc: Free all objects
+ */
+{
+ ComposeObj *o;
+
+ o = Obj;
+ while (Obj != NULL) {
+ switch(Obj->objtype) {
+ case STRINGOBJ:
+ DelStringObj((StringObj *) Obj->obj);
+ break;
+ case LISTOBJ:
+ DelListObj((ListObj *) Obj->obj);
+ break;
+ case BUTTONOBJ:
+ DelButtonObj((ButtonObj *) Obj->obj);
+ break;
+ }
+ Obj = Obj->next;
+ }
+
+ FreeObj(o);
+} /* DelObj() */
+
+/***********************************************************************
+ *
+ * StringObj routines
+ *
+ ***********************************************************************/
+
+void
+RefreshStringObj(StringObj *so)
+/*
+ * Desc: redraw the object
+ */
+{
+ char tmp[512];
+
+ wmove(so->win, so->y, so->x+1);
+ wattrset(so->win, dialog_attr);
+ waddstr(so->win, so->title);
+
+ draw_box(so->win, so->y+1, so->x, 3, so->w, dialog_attr, border_attr);
+ wattrset(so->win, item_attr);
+ wmove(so->win, so->y+2, so->x+1);
+ if (strlen(so->s) > so->w-2) {
+ strncpy(tmp, (char *) so->s + strlen(so->s) - so->w + 2, so->w - 1);
+ waddstr(so->win, tmp);
+ } else {
+ waddstr(so->win, so->s);
+ }
+
+ return;
+} /* RefreshStringObj() */
+
+StringObj *
+NewStringObj(WINDOW *win, char *title, char *s, int y, int x, int w, int len)
+/*
+ * Desc: Initialize a new stringobj and return a pointer to it.
+ * Draw the object on the screen at the specified coordinates
+ */
+{
+ StringObj *so;
+
+ /* Initialize a new object */
+ so = (StringObj *) malloc( sizeof(StringObj) );
+ if (!so) {
+ printf("NewStringObj: Error malloc'ing StringObj\n");
+ exit(-1);
+ }
+ so->title = (char *) malloc( strlen(title) + 1);
+ if (!so->title) {
+ printf("NewStringObj: Error malloc'ing so->title\n");
+ exit(-1);
+ }
+ strcpy(so->title, title);
+ so->s = s;
+ strcpy(so->s, s);
+ so->x = x;
+ so->y = y;
+ so->w = w;
+ so->len = len;
+ so->win = win;
+
+ /* Draw it on the screen */
+ RefreshStringObj(so);
+
+ return(so);
+} /* NewStringObj() */
+
+int
+SelectStringObj(StringObj *so)
+/*
+ * Desc: get input using the info in <so>
+ */
+{
+ int key;
+ char tmp[so->len+1];
+
+ strcpy(tmp, so->s);
+ key = line_edit(so->win, so->y+2, so->x+1,
+ so->len, so->w-2, inputbox_attr, TRUE, tmp);
+ if ((key == '\n') || (key == '\r') || (key == '\t') || key == (KEY_BTAB) ) {
+ strcpy(so->s, tmp);
+ }
+ RefreshStringObj(so);
+ if (key == ESC) {
+ return(SEL_ESC);
+ }
+ if (key == '\t') {
+ return(SEL_TAB);
+ }
+ if ( (key == KEY_BTAB) || (key == KEY_F(2)) ) {
+ return(SEL_BACKTAB);
+ }
+ if ((key == '\n') || (key == '\r')) {
+ return(SEL_CR);
+ }
+ return(key);
+} /* SelectStringObj() */
+
+
+void
+DelStringObj(StringObj *so)
+/*
+ * Desc: Free the space occupied by <so>
+ */
+{
+ free(so->title);
+ free(so);
+
+ return;
+}
+
+/***********************************************************************
+ *
+ * ListObj routines
+ *
+ ***********************************************************************/
+
+void
+DrawNames(ListObj *lo)
+/*
+ * Desc: Just refresh the names, not the surrounding box and title
+ */
+{
+ int i, j, h, x, y;
+ char tmp[MAXPATHLEN];
+
+ x = lo->x + 1;
+ y = lo->y + 2;
+ h = lo->h - 2;
+ for (i=lo->scroll; i<lo->n && i<lo->scroll+h; i++) {
+ wmove(lo->win, y+i-lo->scroll, x);
+ if (lo->seld[i]) {
+ wattrset(lo->win, A_BOLD);
+ } else {
+ wattrset(lo->win, item_attr);
+ }
+ if (strlen(lo->name[i]) > lo->w-2) {
+ strncpy(tmp, lo->name[i], lo->w-2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[i]);
+ for (j=strlen(lo->name[i]); j<lo->w-2; j++) waddstr(lo->win, " ");
+ }
+ }
+ wattrset(lo->win, item_attr);
+ while (i<lo->scroll+h) {
+ wmove(lo->win, y+i-lo->scroll, x);
+ for (j=0; j<lo->w-2; j++) waddstr(lo->win, " ");
+ i++;
+ }
+
+ return;
+} /* DrawNames() */
+
+void
+RefreshListObj(ListObj *lo)
+/*
+ * Desc: redraw the list object
+ */
+{
+ char perc[7];
+
+ /* setup the box */
+ wmove(lo->win, lo->y, lo->x+1);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, lo->title);
+ draw_box(lo->win, lo->y+1, lo->x, lo->h, lo->w, dialog_attr, border_attr);
+
+ /* draw the names */
+ DrawNames(lo);
+
+ /* Draw % indication */
+ sprintf(perc, "(%3d%%)", MIN(100, (int) (100 * (lo->sel+lo->h-2) / MAX(1, lo->n))));
+ wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, perc);
+
+
+ return;
+} /* RefreshListObj() */
+
+ListObj *
+NewListObj(WINDOW *win, char *title, char **list, char *listelt, int y, int x,
+ int h, int w, int n)
+/*
+ * Desc: create a listobj, draw it on the screen and return a pointer to it.
+ */
+{
+ ListObj *lo;
+ int i;
+
+ /* Initialize a new object */
+ lo = (ListObj *) malloc( sizeof(ListObj) );
+ if (!lo) {
+ fprintf(stderr, "NewListObj: Error malloc'ing ListObj\n");
+ exit(-1);
+ }
+ lo->title = (char *) malloc( strlen(title) + 1);
+ if (!lo->title) {
+ fprintf(stderr, "NewListObj: Error malloc'ing lo->title\n");
+ exit(-1);
+ }
+ strcpy(lo->title, title);
+ lo->name = list;
+ if (n>0) {
+ lo->seld = (int *) malloc( n * sizeof(int) );
+ if (!lo->seld) {
+ fprintf(stderr, "NewListObj: Error malloc'ing lo->seld\n");
+ exit(-1);
+ }
+ for (i=0; i<n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ } else {
+ lo->seld = NULL;
+ }
+ lo->y = y;
+ lo->x = x;
+ lo->w = w;
+ lo->h = h;
+ lo->n = n;
+ lo->scroll = 0;
+ lo->sel = 0;
+ lo->elt = listelt;
+ lo->win = win;
+
+ /* Draw the object on the screen */
+ RefreshListObj(lo);
+
+ return(lo);
+} /* NewListObj() */
+
+void
+UpdateListObj(ListObj *lo, char **list, int n)
+/*
+ * Desc: Update the list in the listobject with the provided list
+ * Pre: lo->name "has been freed"
+ * "(A i: 0<=i<lo->n: "lo->name[i] has been freed")"
+ */
+{
+ int i;
+
+ if (lo->seld) {
+ free(lo->seld);
+ }
+
+ /* Rewrite the list in the object */
+ lo->name = list;
+ if (n>0) {
+ lo->seld = (int *) malloc( n * sizeof(int) );
+ if (!lo->seld) {
+ fprintf(stderr, "UpdateListObj: Error malloc'ing lo->seld\n");
+ exit(-1);
+ }
+ for (i=0; i<n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ } else {
+ lo->seld = NULL;
+ }
+ lo->n = n;
+ lo->scroll = 0;
+ lo->sel = 0;
+
+ /* Draw the object on the screen */
+ RefreshListObj(lo);
+
+ return;
+} /* UpdateListObj() */
+
+int
+SelectListObj(ListObj *lo)
+/*
+ * Desc: get a listname (or listnames), TAB to move on, or ESC ESC to exit
+ * Pre: lo->n >= 1
+ */
+{
+ int key, sel_x, sel_y, quit;
+ char tmp[MAXPATHLEN];
+ char perc[4];
+
+ sel_x = lo->x+1;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+
+ if (lo->n == 0) return(SEL_TAB);
+
+ keypad(lo->win, TRUE);
+
+ /* Draw current selection in inverse video */
+ wmove(lo->win, sel_y, sel_x);
+ wattrset(lo->win, item_selected_attr);
+ waddstr(lo->win, lo->name[lo->sel]);
+
+ key = wgetch(lo->win);
+ quit = FALSE;
+ while ((key != '\t') && (key != '\n') && (key != '\r')
+ && (key != ESC) && (key != KEY_F(1)) && (key != '?') && !quit) {
+ /* first draw current item in normal video */
+ wmove(lo->win, sel_y, sel_x);
+ if (lo->seld[lo->sel]) {
+ wattrset(lo->win, A_BOLD);
+ } else {
+ wattrset(lo->win, item_attr);
+ }
+ if (strlen(lo->name[lo->sel]) > lo->w - 2) {
+ strncpy(tmp, lo->name[lo->sel], lo->w - 2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[lo->sel]);
+ }
+
+ switch (key) {
+ case KEY_DOWN:
+ case ctrl('n'):
+ if (sel_y < lo->y + lo->h-1) {
+ if (lo->sel < lo->n-1) {
+ sel_y++;
+ lo->sel++;
+ }
+ } else {
+ if (lo->sel < lo->n-1) {
+ lo->sel++;
+ lo->scroll++;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ }
+ break;
+ case KEY_UP:
+ case ctrl('p'):
+ if (sel_y > lo->y+2) {
+ if (lo->sel > 0) {
+ sel_y--;
+ lo->sel--;
+ }
+ } else {
+ if (lo->sel > 0) {
+ lo->sel--;
+ lo->scroll--;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ }
+ break;
+ case KEY_HOME:
+ case ctrl('a'):
+ lo->sel = 0;
+ lo->scroll = 0;
+ sel_y = lo->y + 2;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ case KEY_END:
+ case ctrl('e'):
+ if (lo->n < lo->h - 3) {
+ lo->sel = lo->n-1;
+ lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ } else {
+ /* more than one page of list */
+ lo->sel = lo->n-1;
+ lo->scroll = lo->n-1 - (lo->h-3);
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ }
+ break;
+ case KEY_NPAGE:
+ case ctrl('f'):
+ lo->sel += lo->h - 2;
+ if (lo->sel >= lo->n) lo->sel = lo->n - 1;
+ lo->scroll += lo->h - 2;
+ if (lo->scroll >= lo->n - 1) lo->scroll = lo->n - 1;
+ if (lo->scroll < 0) lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ case KEY_PPAGE:
+ case ctrl('b'):
+ lo->sel -= lo->h - 2;
+ if (lo->sel < 0) lo->sel = 0;
+ lo->scroll -= lo->h - 2;
+ if (lo->scroll < 0) lo->scroll = 0;
+ sel_y = lo->y + 2 + lo->sel - lo->scroll;
+ DrawNames(lo);
+ wrefresh(lo->win);
+ break;
+ default:
+ quit = TRUE;
+ break;
+ }
+ /* Draw % indication */
+ sprintf(perc, "(%3d%%)", MIN(100, (int)
+ (100 * (lo->sel+lo->h - 2) / MAX(1, lo->n))));
+ wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8);
+ wattrset(lo->win, dialog_attr);
+ waddstr(lo->win, perc);
+
+ /* draw current item in inverse */
+ wmove(lo->win, sel_y, sel_x);
+ wattrset(lo->win, item_selected_attr);
+ if (strlen(lo->name[lo->sel]) > lo->w - 2) {
+ /* when printing in inverse video show the last characters in the */
+ /* name that will fit in the window */
+ strncpy(tmp,
+ lo->name[lo->sel] + strlen(lo->name[lo->sel]) - (lo->w - 2),
+ lo->w - 2);
+ tmp[lo->w - 2] = 0;
+ waddstr(lo->win, tmp);
+ } else {
+ waddstr(lo->win, lo->name[lo->sel]);
+ }
+ if (!quit) key = wgetch(lo->win);
+ }
+
+ if (key == ESC) {
+ return(SEL_ESC);
+ }
+ if (key == '\t') {
+ return(SEL_TAB);
+ }
+ if ((key == KEY_BTAB) || (key == ctrl('b'))) {
+ return(SEL_BACKTAB);
+ }
+ if ((key == '\n') || (key == '\r')) {
+ strcpy(lo->elt, lo->name[lo->sel]);
+ return(SEL_CR);
+ }
+ return(key);
+} /* SelectListObj() */
+
+void
+DelListObj(ListObj *lo)
+/*
+ * Desc: Free the space occupied by the listobject
+ */
+{
+ free(lo->title);
+ if (lo->seld != NULL) free(lo->seld);
+ free(lo);
+
+ return;
+} /* DelListObj() */
+
+void
+MarkCurrentListObj(ListObj *lo)
+/*
+ * Desc: mark the current item for the selection list
+ */
+{
+ lo->seld[lo->sel] = !(lo->seld[lo->sel]);
+ DrawNames(lo);
+
+ return;
+} /* MarkCurrentListObj() */
+
+void
+MarkAllListObj(ListObj *lo)
+/*
+ * Desc: mark all items
+ */
+{
+ int i;
+
+ for (i=0; i<lo->n; i++) {
+ lo->seld[i] = TRUE;
+ }
+ DrawNames(lo);
+
+ return;
+} /* MarkAllListObj() */
+
+void
+UnMarkAllListObj(ListObj *lo)
+/*
+ * Desc: unmark all items
+ */
+{
+ int i;
+
+ for (i=0; i<lo->n; i++) {
+ lo->seld[i] = FALSE;
+ }
+ DrawNames(lo);
+
+ return;
+} /* UnMarkAllListObj() */
+
+
+/***********************************************************************
+ *
+ * ButtonObj routines
+ *
+ ***********************************************************************/
+
+
+void
+RefreshButtonObj(ButtonObj *bo)
+/*
+ * Desc: redraw the button
+ */
+{
+ draw_box(bo->win, bo->y, bo->x, 3, bo->w, dialog_attr, border_attr);
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE);
+
+ return;
+} /* RefreshButtonObj() */
+
+ButtonObj *
+NewButtonObj(WINDOW *win, char *title, int *pushed, int y, int x)
+/*
+ * Desc: Create a new button object
+ */
+{
+ ButtonObj *bo;
+
+ bo = (ButtonObj *) malloc( sizeof(ButtonObj) );
+
+ bo->win = win;
+ bo->title = (char *) malloc( strlen(title) + 1);
+ strcpy(bo->title, title);
+ bo->x = x;
+ bo->y = y;
+ bo->w = strlen(title) + 6;
+ bo->h = 3;
+ bo->pushed = pushed;
+
+ RefreshButtonObj(bo);
+
+ return(bo);
+} /* NewButtonObj() */
+
+int
+SelectButtonObj(ButtonObj *bo)
+/*
+ * Desc: Wait for buttonpresses or TAB's to move on, or ESC ESC
+ */
+{
+ int key;
+
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, TRUE);
+ wmove(bo->win, bo->y+1, bo->x+(bo->w/2)-1);
+ key = wgetch(bo->win);
+ print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE);
+ switch(key) {
+ case '\t':
+ return(SEL_TAB);
+ break;
+ case KEY_BTAB:
+ case ctrl('b'):
+ return(SEL_BACKTAB);
+ case '\n':
+ *(bo->pushed) = TRUE;
+ return(SEL_BUTTON);
+ break;
+ case ESC:
+ return(SEL_ESC);
+ break;
+ default:
+ return(key);
+ break;
+ }
+} /* SelectButtonObj() */
+
+void
+DelButtonObj(ButtonObj *bo)
+/*
+ * Desc: Free the space occupied by <bo>
+ */
+{
+ free(bo->title);
+ free(bo);
+
+ return;
+} /* DelButtonObj() */
diff --git a/gnu/lib/libdialog/ui_objects.h b/gnu/lib/libdialog/ui_objects.h
new file mode 100644
index 0000000..db9a12c
--- /dev/null
+++ b/gnu/lib/libdialog/ui_objects.h
@@ -0,0 +1,113 @@
+/*
+ * Author: Marc van Kempen
+ * Desc: include file for UI-objects
+ *
+ * Copyright (c) 1995, Marc van Kempen
+ *
+ * All rights reserved.
+ *
+ * This software may be used, modified, copied, distributed, and
+ * sold, in both source and binary form provided that the above
+ * copyright and these terms are retained, verbatim, as the first
+ * lines of this file. Under no circumstances is the author
+ * responsible for the proper functioning of this software, nor does
+ * the author assume any responsibility for damages incurred with
+ * its use.
+ *
+ */
+
+#include "dialog.h"
+#include <ncurses.h>
+
+/***********************************************************************
+ *
+ * Defines
+ *
+ ***********************************************************************/
+
+#define ctrl(a) ((a) - 'a' + 1)
+
+/* the Object types */
+#define STRINGOBJ 1
+#define LISTOBJ 2
+#define BUTTONOBJ 3
+
+/* the return signals from the selection routines */
+/* 1000 and higher should avoid conflicts with keys pressed */
+#define SEL_CR 1001 /* return was pressed */
+#define SEL_ESC 1002 /* ESC pressed */
+#define SEL_TAB 1003 /* TAB pressed */
+#define SEL_BACKTAB 1004 /* SHIFT-TAB pressed */
+#define SEL_BUTTON 1005 /* a button was pressed */
+
+/***********************************************************************
+ *
+ * Typedefs
+ *
+ ***********************************************************************/
+
+typedef struct {
+ WINDOW *win; /* the window it's contained in */
+ char *title; /* the prompt for the input field */
+ char *s; /* initial value of the input field */
+ int x, y, w, len; /* the (y, x) position of the upperleft */
+ /* corner and the width <w> of the display */
+ /* and length <len> of the field */
+} StringObj;
+
+typedef struct {
+ WINDOW *win; /* the windows it's contained in */
+ char *title; /* the title of the list */
+ char **name; /* the names of the list */
+ int *seld; /* the currently selected names */
+ char *elt; /* the current element in the list list[sel] */
+ int x, y, w, h, n; /* dimensions of list and # of elements (n) */
+ int scroll, sel; /* current position in the list */
+} ListObj;
+
+typedef struct {
+ WINDOW *win; /* the window it's contained in */
+ char *title; /* title for the button */
+ int x, y, w, h; /* its dimensions */
+ int *pushed; /* boolean that determines wether button was pushed */
+} ButtonObj;
+
+typedef struct ComposeObj {
+ int objtype;
+ void *obj;
+ struct ComposeObj *next, *prev;
+} ComposeObj;
+
+/**********************************************************************
+ *
+ * Prototypes
+ *
+ **********************************************************************/
+
+void RefreshStringObj(StringObj *so);
+StringObj *NewStringObj(WINDOW *win, char *title, char *s,
+ int y, int x, int w, int len);
+int SelectStringObj(StringObj *so);
+void DelStringObj(StringObj *so);
+
+void RefreshListObj(ListObj *lo);
+ListObj *NewListObj(WINDOW *win, char *title, char **list,
+ char *listelt, int y, int x, int h, int w, int n);
+void UpdateListObj(ListObj *lo, char **list, int n);
+int SelectListObj(ListObj *lo);
+void DelListObj(ListObj *obj);
+void MarkCurrentListObj(ListObj *lo);
+void MarkAllListObj(ListObj *lo);
+void UnMarkAllListObj(ListObj *lo);
+
+void RefreshButtonObj(ButtonObj *bo);
+ButtonObj *NewButtonObj(WINDOW *win, char *title, int *pushed,
+ int y, int x);
+int SelectButtonObj(ButtonObj *bo);
+void DelButtonObj(ButtonObj *bo);
+void AddObj(ComposeObj **Obj, int objtype, void *obj);
+void FreeObj(ComposeObj *Obj);
+int ReadObj(ComposeObj *Obj);
+int PollObj(ComposeObj **Obj);
+void DelObj(ComposeObj *Obj);
+
diff --git a/gnu/lib/libdialog/yesno.c b/gnu/lib/libdialog/yesno.c
new file mode 100644
index 0000000..2390821
--- /dev/null
+++ b/gnu/lib/libdialog/yesno.c
@@ -0,0 +1,149 @@
+/*
+ * yesno.c -- implements the yes/no box
+ *
+ * AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <dialog.h>
+#include "dialog.priv.h"
+
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int width)
+{
+ int i, j, x, y, key = 0, button = 0;
+ WINDOW *dialog;
+ char *tmphlp;
+
+ /* disable helpline */
+ tmphlp = get_helpline();
+ use_helpline(NULL);
+
+ if (height < 0)
+ height = strheight(prompt)+4;
+ if (width < 0) {
+ i = strwidth(prompt);
+ j = ((title != NULL) ? strwidth(title) : 0);
+ width = MAX(i,j)+4;
+ }
+ width = MAX(width,23);
+
+ if (width > COLS)
+ width = COLS;
+ if (height > LINES)
+ height = LINES;
+ /* center dialog box on screen */
+ x = DialogX ? DialogX : (COLS - width)/2;
+ y = DialogY ? DialogY : (LINES - height)/2;
+
+#ifdef HAVE_NCURSES
+ if (use_shadow)
+ draw_shadow(stdscr, y, x, height, width);
+#endif
+ dialog = newwin(height, width, y, x);
+ if (dialog == NULL) {
+ endwin();
+ fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
+ exit(1);
+ }
+ keypad(dialog, TRUE);
+
+ draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+ wattrset(dialog, border_attr);
+ wmove(dialog, height-3, 0);
+ waddch(dialog, ACS_LTEE);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ACS_HLINE);
+ wattrset(dialog, dialog_attr);
+ waddch(dialog, ACS_RTEE);
+ wmove(dialog, height-2, 1);
+ for (i = 0; i < width-2; i++)
+ waddch(dialog, ' ');
+
+ if (title != NULL) {
+ wattrset(dialog, title_attr);
+ wmove(dialog, 0, (width - strlen(title))/2 - 1);
+ waddch(dialog, ' ');
+ waddstr(dialog, title);
+ waddch(dialog, ' ');
+ }
+ wattrset(dialog, dialog_attr);
+ wmove(dialog, 1, 2);
+ print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
+
+ display_helpline(dialog, height-1, width);
+
+ x = width/2-10;
+ y = height-2;
+ print_button(dialog, " No ", y, x+13, FALSE);
+ print_button(dialog, " Yes ", y, x, TRUE);
+ wrefresh(dialog);
+
+ while (key != ESC) {
+ key = wgetch(dialog);
+ switch (key) {
+ case 'Y':
+ case 'y':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return 0;
+ case 'N':
+ case 'n':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return 1;
+ case KEY_BTAB:
+ case TAB:
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ if (!button) {
+ button = 1; /* Indicates "No" button is selected */
+ print_button(dialog, " Yes ", y, x, FALSE);
+ print_button(dialog, " No ", y, x+13, TRUE);
+ }
+ else {
+ button = 0; /* Indicates "Yes" button is selected */
+ print_button(dialog, " No ", y, x+13, FALSE);
+ print_button(dialog, " Yes ", y, x, TRUE);
+ }
+ wrefresh(dialog);
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return button;
+ case ESC:
+ break;
+ case KEY_F(1):
+ case '?':
+ display_helpfile();
+ break;
+ }
+ }
+
+ delwin(dialog);
+ restore_helpline(tmphlp);
+ return -1; /* ESC pressed */
+}
+/* End of dialog_yesno() */
diff --git a/gnu/lib/libg++/Makefile b/gnu/lib/libg++/Makefile
new file mode 100644
index 0000000..f00cbcf
--- /dev/null
+++ b/gnu/lib/libg++/Makefile
@@ -0,0 +1,52 @@
+#
+# $Id: Makefile,v 1.15 1996/10/04 15:11:42 peter Exp $
+#
+
+GPPDIR= ${.CURDIR}/../../../contrib/libg++
+
+.PATH: ${GPPDIR}/libiberty ${GPPDIR}/libio ${GPPDIR}/libg++/src ${GPPDIR}/librx
+
+SUBDIR+= doc
+
+LIB= g++
+SHLIB_MAJOR= 4
+SHLIB_MINOR= 0
+CPLUSPLUSLIB= 1 # include c++rt0.o for static constructors
+
+CFLAGS+= -I${GPPDIR}/include -I/usr/include/g++
+CXXFLAGS+= -I${GPPDIR}/include -I${GPPDIR}/libio -I${GPPDIR}/libstdc++
+
+# C source
+SRCS= bitand.c bitany.c bitblt.c bitclear.c bitcopy.c bitcount.c \
+ bitinvert.c bitlcomp.c bitset1.c bitxor.c timer.c
+
+# C source for librx
+SRCS+= rx.c
+
+# C++ source
+SRCS+= ACG.cc AllocRing.cc Binomial.cc BitSet.cc BitString.cc DLList.cc \
+ DiscUnif.cc Erlang.cc Fix.cc Fix16.cc Fix24.cc Geom.cc GetOpt.cc \
+ HypGeom.cc Intdouble.cc Integer.cc LogNorm.cc MLCG.cc NegExp.cc \
+ Normal.cc Obstack.cc Poisson.cc RNG.cc Random.cc Rational.cc \
+ Regex.cc RndInt.cc SLList.cc SmplHist.cc SmplStat.cc String.cc \
+ Uniform.cc Weibull.cc \
+ builtin.cc compare.cc error.cc fmtq.cc gcd.cc hash.cc ioob.cc \
+ lg.cc pow.cc sqrt.cc
+
+# "normal" headers (no CursesW.h[its useless], no bool.h[in stdc++])
+HDRS= ACG.h AllocRing.h Binomial.h BitSet.h BitString.h Complex.h \
+ DLList.h DiscUnif.h Erlang.h Fix.h Fix16.h Fix24.h Geom.h GetOpt.h \
+ HypGeom.h Incremental.h Integer.h LogNorm.h MLCG.h NegExp.h Normal.h \
+ Obstack.h Pix.h Poisson.h RNG.h Random.h Rational.h Regex.h RndInt.h \
+ SLList.h SmplHist.h SmplStat.h String.h Uniform.h Weibull.h \
+ bitdo1.h bitdo2.h bitprims.h builtin.h compare.h generic.h \
+ getpagesize.h libc.h minmax.h osfcn.h std.h strclass.h swap.h \
+ sysent.h typemacros.h
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${HDRS:S;^;${GPPDIR}/libg++/src/;} \
+ ${GPPDIR}/librx/rx.h \
+ ${DESTDIR}/usr/include/g++
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libg++/doc/Makefile b/gnu/lib/libg++/doc/Makefile
new file mode 100644
index 0000000..c3a584c
--- /dev/null
+++ b/gnu/lib/libg++/doc/Makefile
@@ -0,0 +1,14 @@
+# $Id$
+
+INFO = g++FAQ libg++ iostream
+
+.PATH: ${.CURDIR}/../../../../contrib/libg++/libg++
+.PATH: ${.CURDIR}/../../../../contrib/libg++/libio
+
+# HACK ALERT!
+CLEANFILES+= lgpl.texinfo
+libg++.info: lgpl.texinfo
+lgpl.texinfo:
+ echo "See the file: /usr/src/gnu/COPYING.LIB" > lgpl.texinfo
+
+.include <bsd.info.mk>
diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile
new file mode 100644
index 0000000..9117c52
--- /dev/null
+++ b/gnu/lib/libgcc/Makefile
@@ -0,0 +1,95 @@
+#
+# $Id: Makefile,v 1.12 1996/09/21 14:27:38 peter Exp $
+#
+
+LIB= gcc
+
+# Install libgcc_pic.a, since ld.so uses it.
+INSTALL_PIC_ARCHIVE= yes
+
+#
+# XXX This is a hack, but it seems to work. libgcc1.a is supposed to be
+# compiled by the native compiler, and libgcc2.a is meant to be compiled
+# by *this* version of gcc.
+#
+# Normally, this does not make any difference, since we only have gcc, but
+# when bootstrapping from gcc-2.6.3, we have to use the freshly built 2.7.2
+# compiler for some of the libgcc2.c __attribute__ stuff.
+#
+.if exists(${.OBJDIR}/../cc)
+XCC= ${.OBJDIR}/../cc/cc
+.else
+XCC= ${.CURDIR}/../cc/cc
+.endif
+
+.if exists(${.OBJDIR}/../cc1)
+XCC+= -B${.OBJDIR}/../cc1/
+.else
+XCC+= -B${.CURDIR}/../cc1/
+.endif
+
+.if exists(${.OBJDIR}/../cpp)
+XCC+= -B${.OBJDIR}/../cpp/
+.else
+XCC+= -B${.CURDIR}/../cpp/
+.endif
+
+# Members of libgcc1.a.
+LIB1FUNCS= _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
+ _lshrsi3 _ashrsi3 _ashlsi3 \
+ _divdf3 _muldf3 _negdf2 _adddf3 _subdf3 \
+ _fixdfsi _fixsfsi _floatsidf _floatsisf _truncdfsf2 _extendsfdf2 \
+ _addsf3 _negsf2 _subsf3 _mulsf3 _divsf3 \
+ _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
+ _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
+
+# Library members defined in libgcc2.c.
+LIB2FUNCS= _muldi3 _divdi3 _moddi3 _udivdi3 _umoddi3 _negdi2 \
+ _lshrdi3 _ashldi3 _ashrdi3 _ffsdi2 \
+ _udiv_w_sdiv _udivmoddi4 _cmpdi2 _ucmpdi2 _floatdidf _floatdisf \
+ _fixunsdfsi _fixunssfsi _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi \
+ _fixxfdi _fixunsxfdi _floatdixf _fixunsxfsi \
+ _fixtfdi _fixunstfdi _floatditf \
+ __gcc_bcmp _varargs _eprintf _op_new _op_vnew _new_handler \
+ _op_delete \
+ _op_vdel _bb _shtab _clear_cache _trampoline __main _exit _ctors \
+ _eh _pure
+
+LIB1OBJS=${LIB1FUNCS:T:S@$@.o@}
+LIB2OBJS=${LIB2FUNCS:T:S@$@.o@}
+LIB1SOBJS=${LIB1FUNCS:T:S@$@.so@}
+LIB2SOBJS=${LIB2FUNCS:T:S@$@.so@}
+P1OBJS=${LIB1FUNCS:T:S@$@.po@}
+P2OBJS=${LIB2FUNCS:T:S@$@.po@}
+
+OBJS= ${LIB1OBJS} ${LIB2OBJS}
+
+${LIB1OBJS}: libgcc1.c
+ ${CC} -c ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc1.c
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${LIB2OBJS}: libgcc2.c
+ ${XCC} -c ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc2.c
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+.if !defined(NOPIC)
+${LIB1SOBJS}: libgcc1.c
+ ${CC} -c -fpic ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc1.c
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${LIB2SOBJS}: libgcc2.c
+ ${XCC} -c -fpic ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc2.c
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+.endif
+
+.if !defined(NOPROFILE)
+${P1OBJS}: libgcc1.c
+ ${CC} -c -p ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc1.c
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+${P2OBJS}: libgcc2.c
+ ${XCC} -c -p ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${GCCDIR}/libgcc2.c
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+.endif
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libgmp/COPYING b/gnu/lib/libgmp/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/lib/libgmp/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <signature of Ty Coon>, 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/gnu/lib/libgmp/COPYING.LIB b/gnu/lib/libgmp/COPYING.LIB
new file mode 100644
index 0000000..92b8903
--- /dev/null
+++ b/gnu/lib/libgmp/COPYING.LIB
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 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.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, 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 library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, 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 companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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
+ 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/gnu/lib/libgmp/ChangeLog b/gnu/lib/libgmp/ChangeLog
new file mode 100644
index 0000000..1c29f1e
--- /dev/null
+++ b/gnu/lib/libgmp/ChangeLog
@@ -0,0 +1,3193 @@
+Thu Jun 6 19:00:53 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Version 2.0.2 released.
+
+ * install.sh: New file.
+ * Makefile.in (INSTALL): Use install.sh.
+ (install-normal): New name for target `install'.
+ (install): New dummy target.
+
+ * mpz/pow_ui.c: Swap tests for (e == 0) and (bsize == 0).
+ * mpz/ui_pow_ui.c: Swap tests for (e == 0) and (blimb == 0).
+
+ * config/mt-linux (AR_FLAGS): New file.
+ * configure.in: Use config/mt-linux for all linux systems.
+
+Tue Jun 4 03:42:18 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Version 2.0.1 released.
+
+ * mpf/tests/ref.c: Cast result of TMP_ALLOC to the right pointer type.
+
+ * extract-double.c: Test _GMP_IEEE_FLOATS with #if, not plain if.
+
+ * insert-double.c: Don't #include stdlib.h.
+
+ * gmp-impl.h (union ieee_double_extract): Test sparc and __sparc.
+ Do not test __sparc__.
+
+ * mpf/reldiff.c: Change declaration to work around irix5 compiler bug.
+ * mpq/equal.c: Likewise.
+
+ * mpn/generic/gcd.c: Delete spurious comma at end of enumeration.
+
+ * mpn/generic/gcdext.c: Add K&R declaration syntax.
+ * stack-alloc.h: Likewise.
+ * insert-double.c: Likewise.
+ * extract-double.c: Likewise.
+ * mpf/tests/reuse.c: Likewise.
+ * mpz/tests/reuse.c: Likewise.
+ * mpf/tests/t-sub.c: Likewise.
+ * mpf/tests/t-add.c: Likewise.
+ * mpf/tests/t-muldiv.c: Likewise.
+ * mpf/tests/t-conv.c: Likewise.
+ * mpf/tests/ref.c: Likewise.
+
+ * mpn/config/t-oldgas: Renamed from t-freebsd.
+ * mpn/configure.in: Use t-oldgas for freebsd, netbsd, and some linux
+ configurations.
+
+ * mpn/powerpc32/mul_1.s: Really clear cy before entering loop.
+ * mpn/powerpc32/*.s: Fix power/powerpc syntax issues.
+
+ * mpn/config/t-ppc-aix: New file.
+ * mpn/configure.in: Use t-ppc-aix for powerpc like t-pwr-aix for power.
+
+Wed May 29 02:07:31 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h (mp_bits_per_limb): Change qualifier from `const' to
+ __gmp_const.
+
+ * gmp.h (mpf_init_set_str): Add `const' qualifier for 2nd parameter.
+ * mpf/iset_str.c: Likewise.
+
+Mon May 27 00:15:58 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp-impl.h: Declare __gmp_extract_double.
+
+ * mpz/set_q.c: Delete unused variables.
+
+ * gmp.h (mpq_equal): Declare.
+
+ * mpf/eq.c: mpf_cmp2 -> mpf_eq.
+
+Fri May 24 03:20:44 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/iset_d.c: Don't include <math.h>.
+
+ * insert-double.c (__gmp_scale2): New name for scal2.
+ * mpz/get_d.c: Corresponding change.
+ * mpf/get_d.c: Likewise.
+ * mpq/get_d.c: Likewise.
+ * gmp-impl.h: Declare __gmp_scale2.
+
+ * mpn/generic/scan0.c: Clarify comment.
+
+ * mpz/set_q.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpz_set_q.
+
+ * insert-double.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+
+ * mpz/get_d.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpz_get_d.
+
+ * mpf/get_d.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpf_get_d.
+
+ * make.bat: Compile things in alphabetical order.
+
+ * gmp-impl.h (MP_BASE_AS_DOUBLE): New #define.
+ (LIMBS_PER_DOUBLE): New #define.
+
+ * extract-double.c: New file.
+ * Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * mpz/set_d.c: Rewrite to use __gmp_extract_double.
+ * mpf/set_d.c: Likewise.
+
+ * mpn/configure.in: Use t-pwr-aix also for aix 3.2.4 and up.
+
+Wed May 22 02:48:35 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp-impl.h: Rework code for defining ieee_double_extract.
+ (IEEE_DOUBLE_BIG_ENDIAN): Macro removed.
+ (_GMP_IEEE_FLOATS): New macro.
+ * mpn/vax/gmp-mparam.h: Delete.
+
+ * mpn/config/t-pwr-aix: New file.
+ * mpn/configure.in: Use t-pwr-aix for aix 4 and later.
+
+Mon May 20 16:30:31 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h: In code for setting _GMP_H_HAVE_FILE, test more symbols.
+
+ * mpf/tests/t-add.c (oo): Add some `l' printf modifiers.
+ * mpf/tests/t-sub.c (oo): Likewise.
+ * mpf/tests/t-conv.c (oo): Likewise.
+ * mpf/tests/t-sqrt.c (oo): Likewise.
+
+ * mpz/tests/t-mul.c (_mpn_mul_classic): Remove unused variables.
+
+ * mpn/{pyr,i960,clipper}/*.s: Add missing copyright headers.
+
+Fri May 17 02:24:43 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/set_d.c: Call _mpz_realloc.
+
+ * mpq/set_z.c: New file.
+ * mpq/Makefile.in: Compile it.
+ * make.bat: Likewise.
+ * gmp.h: Declare mpq_set_z.
+
+ * mp?/Makefile.in (libmp?.a): Depend on Makefile, not Makefile.in.
+ * mpf/Makefile.in (test): Delete spurious target.
+ * mpq/Makefile.in (test): Likewise.
+
+ * mpf/out_str.c: Use `e' to separate exponent when base <= 10.
+
+ * mpn/configure.in: Treat ultrasparc just like sparc v8,
+ until 64-bit compilers are ready.
+
+ * mpf/set_d.c: Make it work for 64-bit machines.
+
+Thu May 16 20:53:57 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp-impl.h: Set IEEE_DOUBLE_BIG_ENDIAN to 0 for little-endian
+ machines.
+ * mpn/x86/gmp-mparam.h: Delete file.
+
+ * configure.in: Treat microsparc like sparc8.
+
+ * urandom.h: Test __alpha instead of __alpha__, since the former
+ is the standard symbol.
+ * mpn/generic/random2.c: Likewise.
+ * mpf/random2.c: Likewise.
+
+Tue May 14 13:42:39 1996 Torbjorn Granlund (tege@tiny.tmg.se)
+
+ * mpz/set_f.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * gmp.h: Declare mpz_set_f.
+
+ * mpf/set_q.c: Simplify expression in rsize == nsize if-then-else arms.
+
+Tue May 14 13:03:07 1996 Torbjorn Granlund (tege@tiny.tmg.se)
+
+ * make.bat: Add all new files.
+
+Sun May 12 22:24:36 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/set_z.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * gmp.h: Declare mpf_set_z.
+
+Sat May 11 19:26:25 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h: Declare mpf_set_q.
+
+ * mpf/set_q.c: Compute prec-1 limbs in mpn_divrem call.
+
+Fri May 10 17:37:38 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/set_q.c: New file.
+ * mpf/Makefile.in: Compile it.
+
+ * config.sub: Recognize sparc8.
+
+Wed May 8 09:19:11 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/tests/t-dm2exp.c: New file.
+
+ * mpf/tests/t-add.c: Correct header comment.
+ * mpf/tests/t-sub.c: Likewise.
+ * mpf/tests/t-sqrt.c: Likewise.
+
+ * mpf/div.c: Misc variable name cleanups.
+ * mpf/div_ui.c: Base more closely on mpf/div.c.
+ * mpf/ui_div.c: Likewise.
+
+ * mpz/tests/Makefile.in (check): Depend on Makefile.
+ * mpq/tests/Makefile.in (check): Likewise.
+ * mpf/tests/Makefile.in (check): Likewise.
+
+ * mpf/tests/t-muldiv.c: New file.
+ * mpf/tests/Makefile.in: Compile and run `t-muldiv'.
+ (t-ref.o): Delete spurious rule.
+
+ * mpf/sqrt.c: Properly detect negative input operand.
+
+ * mpf/sqrt_ui.c: Delete spurious header comment.
+ * mpf/sqrt.c: Likewise.
+ * mpz/sqrt.c: Likewise.
+
+ * mpz/tests/reuse.c (main): Read `reps' from command line.
+
+ * mpf/tests/reuse.c: New file.
+ * mpf/tests/Makefile.in: Compile and run `reuse'.
+
+ * mpf/mul_ui.c: Disable code for removing low zero limbs.
+
+ * mpf/div.c: Fix condition for when vp and qp overlaps.
+
+ * mpf/add_ui.c: When sum equals u, copy up to prec+1 limbs.
+
+ * mpf/out_str.c: Don't output '\n' after exponent.
+
+ * mpf/add_ui.c: New special case for when U is completely cancelled.
+
+Wed Apr 24 05:33:28 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Version 2.0 released.
+
+ * All files: Upfate FSF's address.
+
+ * Makefile.in (gmp_toc.html): New name for gmp.html.
+ (TAGS): Depend on force.
+
+ * mpf/tests/t-conv.c: Pass -base to mpf_set_str.
+
+Sat Apr 20 03:54:06 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Makefile.in (ps): New target, depend on gmp.ps.
+
+Fri Apr 19 14:03:15 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/out_str.c: Print `@' before exponent, not `e'.
+
+ * make.bat: Update from Makefiles.
+
+Thu Apr 18 01:22:05 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/set_str.c: If parameter `base' is negative, expect exponent
+ to be decimal, otherwise in the same base as the mantissa.
+
+Wed Apr 17 17:28:36 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/set_dfl_prec.c: Don't return anything.
+ * gmp.h: Corresponding changes.
+
+ * mpf/set_dfl_prec.c: Use `unsigned long int' for bit counts.
+ * mpf/init2.c: Likewise.
+ * mpf/get_prc.c: Likewise.
+ * mpf/set_prc.c: Likewise.
+ * mpf/set_prc_raw.c: Likewise.
+ * mpz/popcount.c: Likewise.
+ * mpz/hamdist.c: Likewise.
+ * mpz/scan1.c: Likewise.
+ * mpz/scan0.c: Likewise.
+ * mpn/generic/popcount.c: Likewise.
+ * mpn/generic/hamdist.c: Likewise.
+ * mpn/generic/scan1.c: Likewise.
+ * mpn/generic/scan0.c: Likewise.
+ * gmp.h: Likewise.
+
+ * mpf/eq.c: New file, based on mpf/diff.c.
+ * mpf/diff.c: Delete.
+ * mpf/Makefile.in: Corresponding changes.
+ * gmp.h: Likewise.
+
+ * mpf/reldiff.c: New file.
+ * mpf/Makefile.in: Compile it.
+ * gmp.h: Declare mpf_reldiff.
+
+ * mpz/iset_d.c: New file.
+ * mpz/Makefile.in: Compile it.
+ * gmp.h: Declare mpz_init_set_d.
+
+Tue Apr 16 16:28:31 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Makefile.in (gmp.html): Pass -acc to texi2html.
+
+Mon Apr 15 16:20:24 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/set_str.c: Switch off code for defaulting the base from the
+ leading characters.
+
+ * gmp.h (mp?_sign): Delete.
+ (mp?_sgn): New macros.
+
+Fri Apr 12 17:23:33 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Makefile.in (gmp.dvi): Delete tmp.* at end of rule.
+
+Wed Apr 10 22:52:02 1996 Torbjorn Granlund (tege@tiny.tmg.se)
+
+ * mpf/random2.c: Change of `exp' param, mp_size_t => mp_exp_t.
+ * gmp.h: Corresponding change.
+
+ * gmp.h (mp_bits_per_limb): Make it const.
+
+Sat Mar 30 01:20:23 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * configure.in: Re-enable recognition of with_gcc.
+
+ * mpf/Makefile.in (.c.o): Pass XCFLAGS.
+ * mpn/Makefile.in (.c.o): Likewise.
+ * mpz/Makefile.in (.c.o): Likewise.
+ * mpq/Makefile.in (.c.o): Likewise.
+ * mpbsd/Makefile.in (.c.o): Likewise.
+ * mpf/tests/Makefile.in (.c.o): Likewise.
+ * mpz/tests/Makefile.in (.c.o): Likewise.
+ * mpq/tests/Makefile.in (.c.o): Likewise.
+
+ * Makefile.in (XCFLAGS): Default to empty.
+ (FLAGS_TO_PASS): Pass on XCFLAGS.
+ (.c.o): Pass XCFLAGS.
+
+ * config/mt-m88110 (XCFLAGS): Define instead of CC.
+ * config/mt-sprc8-gcc (XCFLAGS): Likewise.
+ * config/mt-supspc-gcc (XCFLAGS): Likewise.
+
+ * configure: Don't default CC to "gcc -O2" is -with-gcc=no was
+ specified.
+
+Mon Mar 25 01:07:54 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * urandom.h: Test for __SVR4 in addition to __svr4__.
+
+ * mp_bpl.c (mp_bits_per_limb): Declare as `const'.
+
+ * Makefile.in (CFLAGS): `-O2' => `-O'.
+ * mpn/Makefile.in (CFLAGS): Likewise.
+
+ * gmp-impl.h: Get rid of obsolete field access macros.
+
+ * mpn/mp_bases.c (__mp_bases): 1e39 => 1e38 to work around Solaris
+ cc compiler bug.
+
+ * gmp.h (__MPN): Make it work also for non-ANSI compilers.
+
+Thu Mar 21 01:07:54 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/sub.c: New special case for ediff <= 1 before generic code.
+ Simplify generic code for ediff == 0.
+ Rename uexp => exp.
+
+Mon Mar 11 18:24:57 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/tests/*.c: Use ref_mpf_sub for error calculation.
+ * mpf/tests/Makefile.in: Link ref.o to all executables.
+
+ * mpf/tests/t-sub.c: Make u = v + 1 with 50% probability.
+
+Sun Mar 10 21:03:17 1996 Torbjorn Granlund (tege@tiny.tmg.se)
+
+ * mpf/get_str.c: In digit development loop for fractions, change
+ loop condition from `<' to `<='.
+
+Thu Mar 7 04:58:11 1996 Torbjorn Granlund <tege@tiny.tmg.se>
+
+ * mpn/mp_bases.c (__mp_bases): 1e100 => 1e39 to avoid overflow warning.
+
+Wed Mar 6 01:10:42 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpf/tests/t-sqrt.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * mpf/sqrt.c: Special case for square root of zero.
+
+ * mpq/add.c: Clean up variable names.
+ * mpq/sub.c: Update from mpq/add.c.
+
+ * mpz/divexact.c: abs => ABS.
+ * mpz/gcd.c: Likewise. Rewrite final fixup code, to decrease
+ allocation. Misc cleanups.
+
+Tue Mar 5 22:24:56 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpn/configure.in: Recognize linuxoldld as a synonym for linuxaout.
+
+ * gmp.h (mpn_add, mpn_add_1, mpn_sub, mpn_sub_1): Add prototypes.
+
+ * mpn/configure.in: Use t-freebsd also for netbsd.
+
+Mon Mar 4 15:13:28 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpq/Makefile.in (cmp.o): Depend on longlong.h.
+
+ * mpq/equal.c: New file.
+ * mpq/Makefile.in: Corresponding changes.
+
+ * mpf/tests/t-add.c: New file.
+ * mpf/tests/t-sub.c: Renamed from t-addsub.c.
+ * mpf/tests/ref.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * gmp-impl.h (SIZ, ABSIZ, PTR, EXP, PREC, ALLOC): New #defines.
+
+Sun Mar 3 07:45:46 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpf/set_str.c: In exponentialization code, allocate 3 extra
+ limbs, not just 2.
+
+ * mpf/get_str.c: Allocate sufficient space for tstr.
+ When calculating exp_in_base, round result down.
+
+ * mpf/tests/t-conv.c: New file.
+ * mpf/tests/Makefile.in: Corresponding changes.
+
+ * mp_bpl.c: New file.
+ * gmp.h: Declare it.
+ * Makefile.in: Corresponding changes.
+
+Sat Mar 2 06:27:56 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpf/set_prc_raw.c: New file.
+ * mpf/set_prc.c: Renamed from set_prec.c.
+ * mpf/get_prc.c: New file.
+ * mpf/Makefile.in: Corresponding changes.
+ * gmp.h: Declare new functions.
+
+ * mpn/generic/gcdext.c: Add copyright header.
+
+Fri Mar 1 01:22:24 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpn/configure.in: For ppc601, search "power" before "powerpc32".
+
+ * mp?/Makefile.in (AR_FLAGS): New variable.
+ (libmp?.a): Use it.
+
+ * make.bat: New file.
+ * mpn/msdos: New directory.
+ * mpn/msdos/asm-syntax.h: New file.
+
+ * mpn/Makefile.in (distclean maintainer-clean): Delete asm-syntax.h.
+
+ * config.sub: Recognize [ctj]90-cray.
+
+ * mpn/configure.in: Recognize [ctj]90-cray-unicos*.
+
+ * mpn/generic/gcdext.c: Don't use alloca directly, use TMP_* macros.
+
+ * mpn/generic/gcd.c: Split increment from use of USIZE to avoid
+ undefined behaviour.
+
+Thu Feb 29 04:11:24 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * Makefile.in (install-info-files): Update for new install-info
+ behaviour.
+
+ * mpn/power/add_n.s: Rewrite.
+ * mpn/power/sub_n.s: Rewrite.
+
+Wed Feb 28 01:34:30 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpz/pow_ui.c: Compute allocation more aggressively for small bases.
+ * mpz/ui_pow_ui.c: Likewise.
+
+ * mpn/mp_bases.c (__mp_bases): Put huge value in 2nd field for index 1.
+
+ * mpn/generic/sqrtrem.c: sizeof (mp_limb_t) => BYTES_PER_MP_LIMB.
+ * mpn/generic/gcd.c: Likewise.
+ (SIGN_BIT): Compute differently.
+
+Mon Feb 26 00:07:36 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * All files: mp_limb => mp_limb_t, mp_limb_signed => mp_limb_signed_t.
+
+ * Makefile.in (install, install-bsdmp, install-info-files): Depend
+ on installdirs. chmod all installed files.
+
+Sun Feb 25 01:47:41 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpbsd/configure.in: Delete debugging code.
+
+ * All Makefile.in: Update clean targets.
+
+ * Makefile.in (AR_FLAGS): New variable.
+ (libgmp.a): Use it.
+ (libmp.a): Likewise.
+
+ * VERSION: Delete file.
+
+ * Makefile.in (installdirs): New target.
+ * mkinstalldirs: New file (from the texinfo package).
+
+ * Makefile.in (INSTALL, INSTALL_DATA, INSTALL_PROGRAM): New variables.
+ (MAKEINFO, MAKEINFOFLAGS, TEXI2DVI): New variables.
+ (install-info): New target.
+ (install, install-bsdmp): Depend on install-info.
+ ($(srcdir)/gmp.info): Changed from plain gmp.info; put info files
+ into source directory.
+ (distclean, mostlyclean): New targets.
+ (maintainer-clean): New name for realclean.
+ (uninstall): New target.
+ (TAGS): New target.
+ (info, dvi): New targets.
+ (.PHONY): Assign.
+
+ * Makefile.in (install, install-bsdmp): Use INSTALL_DATA.
+
+ * mp{n,z,f,bsd}/move-if-change: Delete.
+
+ * mpbsd/Makefile.in (stamp-stddefh): Delete target.
+
+ * Makefile.in (.c.o): Pass CFLAGS last.
+ * mpbsd/Makefile.in (.c.o): Likewise.
+ * mpf/Makefile.in (.c.o): Likewise.
+ * mpq/Makefile.in (.c.o): Likewise.
+ * mpz/Makefile.in (.c.o): Likewise.
+ * mpn/Makefile.in (.c.o): Likewise.
+ (.S.o): Likewise.
+
+ * memory.c: Change allocation error message.
+
+ * Makefile.in (install): Prefix gmp.h with $(srcdir).
+ (install-bsdmp): Prefix mp.h with $(srcdir).
+
+ * mp{n,z,f,bsd}/{configure,config.sub}: Delete.
+
+ * Makefile.in (gmp.dvi): Set TEXINPUTS also for 2nd tex invocation
+ (install targets): Install gmp.info-N.
+
+Sat Feb 24 03:36:52 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpf/get_str.c: Fix typo.
+
+ * mpz/legendre.c: Clarify expression with extra parens.
+
+ * version.c (gmp_version): Not static.
+
+ * mpf/iset_str.c: Properly return error code.
+
+ * mpf/add.c: Delete unused variables.
+ * mpf/inp_str.c: Likewise.
+ * mpq/get_d.c: Likewise.
+
+ * mpn/generic/dump.c: #include <stdio.h>.
+ * mpf/dump.c: Likewise.
+ * mpf/set_str.c: #include <ctype.h>.
+ (strtol): Declare.
+
+ * gmp.h: mpn_sqrt => mpn_sqrtrem.
+
+ * Makefile.in (clean, realclean): Clean in mpbsd.
+ (check): Test in mpf.
+
+ * mpf/Makefile.in (clean): Clean in tests.
+ * mpq/Makefile.in (clean): Clean in tests.
+
+ * mpf/tests/Makefile.in: New file.
+ * mpf/tests/configure.in: New file.
+ * mpf/tests/t-addsub.c: New file.
+
+ * mpf/sub_ui.c: Simply call mpf_sub for now.
+
+ * mpf/sub.c: Increase prec by 1.
+ * mpf/ui_sub.c: Likewise.
+
+Fri Feb 23 00:59:54 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpf/ui_sub.c: Fix typos.
+
+ * mpf/get_str.c: When allocating space for tmp, allow for an extra
+ limb. In code for fraction conversion, add special case for bases
+ that are a power of 2.
+
+ * mpf/out_str.c: Output leading "0.".
+ Default base to 10, before computing string allocation.
+
+ * mpf/get_str.c: Make variables for string size have type size_t.
+ * gmp.h: Corresponding change.
+
+ * mpf/random2.c: Allow creation of prec+1 large mantissas.
+
+ * mpf/add_ui.c: Don't abort if u < 0; special case for u <= 0.
+ Fix typo in MPN_COPY offset.
+ * mpf/sub_ui.c: Analogous changes.
+
+ * mpf/set_prec.c: Rewrite.
+
+ * mpf/init2.c: Compute precision as in set_prec.c.
+
+ * mpf/div_2exp.c: Special case for u == 0.
+ * mpf/mul_2exp.c: Likewise. Write r->_mp_size always.
+
+ * mpf/sqrt_ui.c: mpn_sqrt => mpn_sqrtrem.
+ * mpf/sqrt.c: Likewise. When computing new exponent, round quotient
+ towards -infinity.
+
+ * mpf/add.c: Fix typos.
+ * mpf/sub.c: Fix typos.
+
+Thu Feb 22 00:24:48 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpz/Makefile.in (stamp-stddefh): Delete target.
+ (test): Delete target.
+ * Makefile.in (stamp-stddefh): Delete target.
+ (cre-stddefh.o): Delete target.
+ (gmp.dvi): Set TEXINPUTS before invoking tex.
+
+ * cre-stddefh.c: Delete.
+
+ * mpz/sqrt.c: Fix typo.
+
+ * mpz/powm.c: Special case for mod == 0.
+ * mpz/powm_ui.c: Likewise.
+
+ * mpz/get_si.c: Handle -0x80000000 correctly.
+
+ * mpz/inp_str.c: Now retutns size_t.
+ Make it return number of bytes read or error indication.
+ * mpf/inp_str.c: Likewise.
+
+ * mpz/out_raw.c: Replace by mpz/out_binary.c, with modifications.
+ * mpz/inp_raw.c: Rewrite, using mpz/inp_binary as a base.
+ * mpz/inp_binary.c: Delete.
+
+ * mpn/Makefile.in (XCFLAGS): Remove variable.
+ (.c.o): Don't pass XCFLAGS.
+ (SFLAGS): Set to nothing.
+ (.S.o): Pass SFLAGS, not XCFLAGS.
+
+ * mpn/config/t-freebsd (SFLAGS): New name for XCFLAGS.
+
+ * mpf/out_str.c: Make return number of bytes written or error
+ indication.
+ * mpz/out_str.c: Likewise.
+ * gmp.h: Corresponding changes.
+
+ * gmp.h (__mpz_struct): mp_size_t => int.
+ (__mpq_struct): Likewise.
+ (__mpf_struct): Likewise.
+ (mp_size_t): int => long int.
+
+ * mpn/cray: New directory.
+ * mpn/cray/gmp-mparam.h: New file.
+ * mpn/configure.in: Recognize cray variants.
+
+ * Makefile.in: Set defaults for prefix, libdir, etc.
+ (install): New target.
+ (install-bsdmp): New target.
+ (gmp.html): New target.
+
+ * stack-alloc.c (__tmp_alloc): Cast void ptrs to char * in comparison.
+
+Wed Feb 21 04:35:02 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * gmp.h: Sort mpn declarations.
+ (mpn_gcdext): Add declaration.
+
+ * mpn/generic/divrem_1.c: New file.
+ * mpn/Makefile.in (divrem_1.o): New rule.
+ * configure.in (functions): Add divrem_1.
+
+ * mpn/generic/divmod.c: Delete file.
+ * mpn/configure.in (functions): Delete divmod.
+ * Makefile.in (divmod.o): Delete rule.
+ * gmp.h (mpn_divmod): New #define.
+
+ * gmp.h (mpn_next_bit_set): Delete spurious declaration.
+
+ * mpn/generic/divrem.c (default case): In code assigning
+ most_significant_q_limb, move reassignment of n0 into if statement.
+
+ * gmp.h (mpf_inp_str): Fix typo.
+ (mpf_out_str): Make prototype match reality.
+ * mpf/inp_str.c: New file.
+ * mpf/out_str.c: New file.
+ * mpf/Makefile.in: Compile new files.
+
+ * mpn/Makefile.in (dump.o): Fix dependency path.
+ (inlines.o): Likewise.
+
+ * mpn/configure.in: Make m68060 be the same as m68000. Clean up
+ m68k configs.
+
+Tue Feb 20 01:35:11 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpn/generic/sqrtrem.c: Renamed from sqrt.
+ * mpn/configure.in (functions): Corresponding change.
+ * mpn/Makefile.in: Likewise.
+ * mpz/sqrtrem.c: Likewise.
+ * mpz/sqrt.c: Likewise.
+ * mpn/generic/perfsqr.c: Likewise.
+
+ * Makefile.in (clean): Also remove libmp.a.
+ Don't compile cre-conv-tab.c or mp_bases.c.
+ cre-conv-tab.c: Delete file.
+ (gmp.ps): New rule.
+
+ * mpn/mp_bases.c: New file.
+ * mpn/Makefile.in: Compile mp_bases.c.
+
+ * mpz/set_str.c: Skip initial whitespace.
+ * mpf/set_str.c: Likewise.
+ * mpbsd/xtom.c: Likewise.
+
+ * gmp.h: Add missing mpz declarations.
+ Delete all formal parameter names from declarations.
+
+ * mpn/Makefile.in: Add dependencies for .c files.
+
+ * Makefile.in (check): Write recursive make calls separately, not as
+ a loop.
+ (FLAGS_TO_PASS): New variable. Use it for most recursive makes.
+
+Mon Feb 19 01:02:20 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpn/Makefile.in (.S.o): Pipe cpp output to grep in order to delete
+ lines starting with #.
+ (CPP): Set to $(CC) -E to avoid gcc dependency.
+
+ * mpn/m68k/syntax.h (moveql): Define to moveq for MIT_SYNTAX.
+
+ * mpn/hppa/hppa1_1/pa7100/addmul_1.S: Fix typo in s1_ptr alignment
+ code.
+ * mpn/hppa/hppa1_1/pa7100/submul_1.S: Likewise.
+
+ * gmp.h: Fix typos in #defines of recently added mpn functions.
+
+ * mpz/inp_str.c: Skip all whitespace, not just plain space.
+ * mpbsd/min.c: Likewise.
+
+ * mpn/configure.in (functions): Add gcdext.
+ * mpn/generic/gcdext.c: New file.
+
+ * mpz/legendre.c: mpz_div_2exp => mpz_tdiv_q_2exp.
+
+ * gmp.h: Surround mpn declarations with extern "C" { ... }.
+
+ * Makefile.in (check): New target.
+
+ * mpq/get_d.c: Update comments. Use rsize instead of dsize + N_QLIMBS
+ when possible. Add special case for nsize == 0.
+
+ * gmp.h (mpq_get_d): Add declaration.
+ (mpq_canonicalize): Likewise.
+ (mpq_cmp_ui): Likewise.
+ (mpf_diff): Likewise.
+ (mpf_ui_sub): Likewise.
+ (mpf_set_prec): Likewise.
+ (mpf_random2): Likewise.
+
+ * gmp.h (mpz_cmp_ui): New #define.
+ (mpz_cmp_si): New #define.
+ (mpq_cmp_ui): New #define.
+ (mpz_sign): New #define.
+ (mpq_sign): New #define.
+ (mpf_sign): New #define.
+ (mpq_numref): New #define.
+ (mpq_denref): New #define.
+
+ * mpq/set_z.c: File deleted.
+ * mpq/Makefile.in: Corresponding changes.
+
+Sun Feb 18 01:34:47 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpbsd/sdiv.c: Use _mp_realloc, not _mpz_realloc.
+
+ * mpz/inp_binary.c: Default stream to stdin.
+ * mpz/inp_str.c: Likewise.
+ * mpz/inp_raw.c: Likewise.
+ * mpz/out_binary.c: Default stream to stdout.
+ * mpz/out_raw.c: Likewise.
+ * mpz/out_str.c: Likewise.
+
+ * mpbsd/realloc.c: New file.
+ * mpbsd/Makefile.in: Corresponding changes.
+
+ * mpbsd/min.c: Rewrite (base on mpz/inp_str.c).
+ * mpbsd/mtox.c: Rewrite (base on mpz/get_str.c).
+
+ * mpbsd/mout.c: Rewrite (base on mpz/out_str) but make it output
+ spaces in each 10th position.
+ * mpbsd/xtom.c: Rewrite (base on mpz/set_str).
+
+ * mpq/tests/Makefile.in (st-cmp): New file.
+ * mpq/tests/configure.in (srcname): New file.
+
+ * mpz/tests/configure.in (srcname): Fix typo.
+
+ * mpq/cmp.c: Add check using number of significant bits, to avoid
+ general multiplication.
+
+Sat Feb 17 11:58:30 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpq/cmp_ui.c: Store cy_limb after the mpn_mul_1 calls.
+
+ * mpq/tests: New directory.
+ * mpq/tests/t-cmp.c: New file.
+ * mpq/tests/t-cmp_ui.c: New file.
+
+ * mpz/tests/dive.c (main): Generate zero numerator.
+ (get_random_size) : Delete.
+
+ * mpz/divexact.c: Add special case for 0/x.
+
+ * gmp.h (mpz_mod): Add declaration.
+
+Fri Feb 16 18:18:39 1996 Andreas Schwab <schwab@informatik.uni-dortmund.de>
+
+ * mpn/m68k/*: Rewrite code not to use the INSN macros.
+ (L): New macro to properly prefix local labels for ELF.
+
+Fri Feb 16 00:20:56 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * gmp-impl.h (ieee_double_extract): Use plain `unsigned int' for
+ fields.
+ * mpn/generic/inlines.c (_FORCE_INLINES): New #define. Delete
+ conditional __GNUC__.
+ * gmp.h (mpn_add, mpn_sub, mpn_add_1, mpn_sub_1):
+ Only define these if __GNUC__ || _FORCE_INLINES.
+ * mpf/random2.c: Add missing parameter in non-ANSI header.
+ * mpn/generic/gcd.c (SIGN_BIT): Do as #define to work around bug
+ in AIX compilers.
+ * mpq/get_d.c: #define N_QLIMBS.
+ * mpz/divexact.c: Obscure division by 0 to silent compiler warnings.
+ * stack-alloc.c: Cast void* pointer to char* before doing arithmetic
+ on it.
+
+ * Makefile.in (mpbsd/libmpbsd.a): New rule.
+ * configure.in (configdirs): Add mpbsd.
+
+ * gmp.h: Add declarations for a few missing mpn functions.
+
+ * Makefile.in (libmp.a): New rule.
+
+ * mpbsd/mdiv.c: #include "dmincl.c", not "mpz_dmincl.c"
+ * gmp.h: Move #define of __GNU_MP__ into the `#if __GNU_MP__' block.
+ * mp.h: Likewise. Update typedefs from gmp.h.
+ * mpbsd/configure.in: New file.
+ * mpbsd/Makefile.in: New file.
+ * mpbsd/configure: Link to master configure.
+ * mpbsd/config.sub: Link to master config.sub.
+
+ * Makefile.in: Set RANLIB_TEST.
+ * (libgmp.a): Use it.
+ * (libgmp.a): Do ranlib before moving the libgmp.a to the build
+ directory.
+ * mp?/Makefile.in: Don't use or set RANLIB.
+
+Thu Feb 15 16:38:41 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpz/add_ui.c: MP_INT => mpz_t.
+ * mpz/cmp_ui.c: Likewise.
+ * mpz/fac_ui.c: Likewise.
+ * mpz/inp_binary.c: Likewise.
+ * mpz/inp_raw.c: Likewise.
+ * mpz/legendre.c: Likewise.
+ * mpz/jacobi.c: Likewise.
+ * mpz/out_binary.c: Likewise.
+ * mpz/out_raw.c: Likewise.
+ * mpz/random2.c: Likewise.
+ * mpz/random.c: Likewise.
+ * mpz/realloc.c: Likewise.
+
+ * mpz/legendre.c: __mpz_2factor(X) => mpz_scan1(X,0),
+ __mpz_odd_less1_2factor => mpz_scan1(X,1).
+ * mpz/ntsup.c: File deleted.
+ * mpz/Makefile.in: Corresponding changes.
+
+ * mpz/pprime_p: Use mpz_scan1 to avoid looping.
+
+ * mpz/fac_ui.c: Type of `k' and `p' is `unsigned long'.
+ * mpz/pprime_p.c: Pass long to *_ui functions.
+ * mpz/gcdext.c: Likewise.
+ * mpz/fdiv_r_2exp.c: Likewise.
+ * mpz/fac_ui.c: Likewise.
+
+ * mpz/powm.c: Don't use mpn_rshift when mod_shift_cnt is 0.
+
+ * mpz/tests/Makefile.in (st-sqrtrem): Fix typo.
+
+ * mpz/cmp_ui.c: #undef mpz_cmp_ui.
+ * mpz/cmp_si.c: #undef mpz_cmp_si.
+ * gmp.h (mpz_cmp_ui): New #define.
+ (mpz_cmp_si): New #define.
+
+Wed Feb 14 22:11:24 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * gmp.h: Test __cplusplus in addition to __STDC__.
+ * gmp-impl.h: Likewise.
+
+ * gmp.h: Surround declarations with extern "C" { ... }.
+
+Tue Feb 13 15:20:45 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpz/fdiv_r_2exp.c: Use MPN_NORMALIZE.
+ * mpz/tdiv_r_2exp.c: Likewise.
+
+ * mpz/fdiv_r_2exp.c: New file.
+ * mpz/fdiv_q_2exp.c: New file.
+ * mpz/tdiv_r_2exp.c: Renamed from mpz/mod_2exp.c.
+ * mpz/tdiv_q_2exp.c: Renamed from mpz/div_2exp.c
+ * mpz/Makefile.in: Corresponding changes.
+
+ * mpz/scan0.c,scan1.c: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * gmp.h (mpn_normal_size): Delete.
+
+ * config.guess: Update from Cygnus version.
+
+ * mpn/m68k/rshift.S: Use INSN2 macro for lea instructions.
+ * mpn/m68k/lshift.S: Likewise.
+
+ * mpn/configure.in: Fix configuration for plain 68000.
+
+Mon Feb 12 01:06:06 1996 Torbjorn Granlund <tege@tmg.se>
+
+ * mpz/tests/t-powm.c: Generate negative BASE operand.
+
+ * mpz/powm.c: Make result always positive.
+
+Sun Feb 11 01:44:56 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/tests/*.c: Add t- prefix.
+ * mpz/tests/Makefile.in: Corresponding changes.
+ * mpz/tests/configure.in: Update srctrigger.
+
+ * mpz/tests/gcd.c: Generate negative operands.
+ * mpz/tests/gcd2.c: Likewise.
+
+ * mpz/gcdext.c: At end, if G is negative, negate all G, S, and T.
+
+Thu Feb 8 17:16:12 UTC 1996 Ken Weber <kweber@mat.ufrgs.br>
+
+ * mp{z,n}/gcd.c: Change mpn_gcd interface.
+ * gmp.h: Ditto.
+ * gmp.texi: update documentation.
+
+Mon Feb 7 23:58:43 1996 Andreas Schwab <schwab@informatik.uni-dortmund.de>
+
+ * mpn/m68k/{lshift,rshift}.S: New files.
+ * mpn/m68k/syntax.h: New ELF_SYNTAX macros.
+ (MEM_INDX, R, PROLOG, EPILOG): New macros.
+ * mpn/m68k/*.S: Use R macro with register name. Use PROLOG and EPILOG
+ macros. Rename `size' to `s_size' or s1_size to avoid clash with ELF
+ .size directive.
+ * mpn/configure.in: New target m68k-*-linux*.
+
+Wed Feb 7 07:41:31 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * Makefile.in (cre-conv-tab): Workaround for SunOS make.
+
+ * mpz/tests/reuse.c: New file.
+ * mpz/tests/Makefile.in: Handle reuse.c.
+
+Tue Feb 6 11:56:24 UTC 1996 Ken Weber <kweber@mat.ufrgs.br>
+
+ * mpz/gcd.c: Fix g->size when one op is 0 and g == other op.
+
+Tue Feb 6 01:36:39 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h (mpz_divexact): Delete parameter names.
+ (mpz_lcm): Delete spurious declaration.
+
+ * mpz/dmincl.c: Fix typo.
+
+Mon Feb 5 01:11:56 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/generic/gcd.c (gcd_2): Declare consistently.
+
+ * mpz/tdiv_q.c: Optimize division by a single-limb divisor.
+ * mpz/dmincl.c: Likewise.
+
+ * mpz/add.c: Use MPN_NORMALIZE instead of mpn_normal_size.
+ * mpz/sub.c: Likewise.
+ * mpn/generic/sqrt.c: Likewise.
+
+ * mpn/tests/{add_n,sub_n,lshift,rshift}.c: Put garbage in the
+ destination arrays.
+
+Fri Feb 2 02:21:27 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/{jacobi.c,legendre.c,ntsup.c,invert.c}: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * mpn/Makefile.in (INCLUDES): Don't search in `generic'.
+
+Thu Feb 1 02:15:11 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ Change from Ken Weber:
+ * mpz/divexact.c: Make it work when quot is identical to either input.
+
+ * mpf/ui_sub.c: New file.
+ * mpf/Makefile.in: Compile it.
+
+ * gmp-impl.h (MPZ_TMP_INIT): alloca -> TMP_ALLOC.
+ * mpz/{c,f}div_{q,qr,r}.c: Use TMP_DECL/TMP_MARK/TMP_FREE since
+ these use MPZ_TMP_INIT.
+ * mpz/mod.c: Likewise.
+ * mpq/{add,sub}.c: Likewise.
+ * mpq/canonicalize: Likewise.
+
+ * mpq/{add,sub,mul,div}.c: Use mpz_divexact. MP_INT -> mpz_t.
+ * mpq/canonicalize.c: Likewise.
+
+Wed Jan 31 01:45:00 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/generic/gcd.c: Misc changes from Ken.
+
+ * mpz/tests/gcd2.c: New file.
+ * mpz/tests/Makefile.in: Handle gcd2.c.
+
+ * mpn/generic/gcd.c (mpn_gcd): When GCD == ORIG_V, return vsize,
+ not orig_vsize. Fix parameter declaration.
+
+ * mpz/mod_ui.c: Delete file.
+ * mpz/Makefile.in: Don't try to compile mod_ui.
+
+ * mpz/cdiv_*_ui.c): Make them work right.
+ * gmp.h: Declare cdiv*.
+
+Tue Jan 30 02:22:56 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/{cdiv_q.c,cdiv_q_ui.c,cdiv_qr.c,cdiv_qr_ui.c,cdiv_r.c,
+ cdiv_r_ui.c,cdiv_ui.c}: New files.
+ * mpz/Makefile.in: Compile them.
+
+ * All files: Make file permissions right.
+
+ Changes from Ken Weber:
+ * mpn/generic/accelgcd.c: Delete.
+ * mpn/generic/bingcd.c: Delete.
+ * mpn/generic/numbits.c: Delete.
+ * mpn/generic/gcd.c: New file.
+ * mpn/configure.in (functions): Update accordingly.
+ * mpz/divexact.c: New file.
+ * mpz/Makefile.in: Compile divexact.c.
+ * mpz/gcd.c: Rewrite to accommodate for gcd changes in mpn.
+ * gmp.h: declare new functions, delete obsolete declarations.
+ * mpz/tests/dive.c: New file.
+ * mpz/tests/Makefile.in: Handle dive.c.
+
+Mon Jan 29 03:53:24 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/random.c: Handle negative SIZE parameter.
+
+ * mpz/tests/tdiv(_ui).c: New name for tst-dm(_ui).c.
+ * mpz/tests/tst-mdm(_ui).c: Delete.
+ * mpz/tests/fdiv(_ui).c: New test based in tst-mdm(_ui).
+ * mpz/tests/*.c: Get rid of tst- prefix for DOS 8+3 naming.
+ * mpz/tests/Makefile.in: Corresponding changes.
+ * mpz/tests/configure.in: Update srctrigger.
+
+ * mpn/generic/divmod.c: Update from divrem.
+ * mpn/generic/divrem.c: Misc cleanups.
+
+Sun Jan 28 03:25:08 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * All files: Use new TMP_ALLOC interface.
+
+ * mpz/powm_ui.c: Make Jan 25 changes to powm.c also here.
+
+ * mpz/tests/powm_ui.c: New file.
+ * mpz/tests/Makefile.in: Add rules for tst-powm and tst-powm_ui.
+
+ * Makefile.in: Update dependency list.
+ * mpf/Makefile.in: Likewise.
+ * mpz/Makefile.in: Likewise.
+ * mpq/Makefile.in: Likewise.
+ * Makefile.in: Set RANLIB simply to ranlib, and allow configure
+ to override it.
+
+ * mpz/Makefile.in (conf): Delete spurious target.
+ (mp_bases.c): Delete.
+ (cre-conv-tab rules): Delete.
+
+ * Makefile.in (cre-conv-tab): Greatly simplify.
+
+Sat Jan 27 13:38:15 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * stack-alloc.c: New file.
+ * stack-alloc.h: New file.
+
+ * gmp.h (__gmp_inline): Define using __inline__.
+
+Thu Jan 25 00:28:37 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/generic/scan0.c: New file.
+ * mpn/generic/scan1.c: Renamed from next_bit.c.
+ * mpn/configure.in (functions): Include scan0 and scan1.
+
+ * mpn/m68k/*: #include sysdep.h. Use C_GLOBAL_NAME.
+
+ * configure: Update from Cygnus version.
+ * config.guess: Likewise.
+ * config.sub: Likewise.
+ * configure: Pass --nfp to recursive configures.
+
+ * mpz/tests/tst-*.c: Adjust SIZE and reps.
+
+ * mpz/powm.c: Move esize==0 test earlier.
+ In final reduction of rp,rsize, don't call mpn_divmod unless
+ reduction is really needed.
+
+ * mpz/tests/tst-powm.c: Fix thinko in checking code.
+
+ * All files: Get rid of `__' prefix from mpn_* calls and declarations.
+ * gmp.h: #define __MPN.
+ * gmp.h: Use __MPN in #defines for mpn calls.
+
+ * mpn/generic/mul_n.c: Prepend `i' to internal routines.
+ * gmp-impl.h: Add #defines using __MPN for those internal routines.
+
+ * mpn/generic/sqrt.c: Change call to mpn_mul to mpn_mul_n.
+
+Wed Jan 24 13:28:19 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/sparc32/udiv_fp.S: New name for udiv_qrnnd.S.
+ * mpn/sparc32/udiv_nfp.S: New name for v8/udiv_qrnnd.S.
+ * mpn/sparc32/v8/supersparc: New directory.
+ * mpn/sparc32/v8/supersparc/udiv.S: New file.
+
+Tue Jan 23 01:10:11 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ This major contribution is from Ken Weber:
+ * mpn/generic/accelgcd.c: New file.
+ * mpn/generic/bdivmod.c: New file.
+ * mpn/generic/bingcd.c: New file.
+ * mpn/generic/gcd_1.c: Rewrite.
+ * mpn/generic/numbits.c: New file (to go away soon).
+ * mpz/gcd.c: Rewrite.
+ * mpz/tests/tst-gcd.c (SIZE): Now 128.
+ * gmp.h: Declare new functions.
+ * mpn/configure.in (functions): List new files.
+ * gmp-impl.h (MPN_SWAP): Delete.
+ (MPN_LESS_BITS_LIMB, MPN_LESS_BITS, MPN_MORE_BITS): Delete.
+ (MPN_COMPL_INCR, MPN_COMPL): Delete.
+
+Mon Jan 22 02:04:59 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h (mpn_name): New #define.
+
+ * mpn/m88k/mc88110/addmul_1.s: New file.
+ * mpn/m88k/mc88110/add_n.S: New file.
+ * mpn/m88k/mc88110/sub_n.S: New file.
+
+ * mpn/m88k/sub_n.s: Correctly initialize carry.
+
+ * mpn/sparc32/{add_n.S,sub_n.S,lshift.S,rshift.S): `beq' => `be'.
+
+Sun Jan 21 00:04:35 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/sparc64/addmul_1.s: New file.
+ * mpn/sparc64/submul_1.s: New file.
+ * mpn/sparc64/rshift.s: New file.
+
+Sat Jan 20 00:32:54 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpz/iset.c: Fix typo introduced Dec 25.
+
+Wed Jan 17 13:16:44 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * config/mt-sprc8-gcc: New name for mt-sparc8-gcc.
+ * config/mt-sparcv8-gcc: Delete.
+ * configure.in: Corresponding changes.
+
+Tue Jan 16 16:31:01 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp-impl.h: #include alloca.h when necessary.
+
+ * longlong.h: Test __alpha instead of __alpha__, since the former
+ is the standard symbol.
+
+Mon Jan 15 18:06:57 1996 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/sparc64/mul_1.s: Swap operands of mulx instructions.
+ * mpn/sparc64/lshift.s: New file.
+
+Fri Dec 29 17:34:03 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/x86/pentium/add_n.S: Get rid of #defines for register names.
+ * mpn/x86/pentium/sub_n.S: Likewise.
+
+Thu Dec 28 03:16:57 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/x86/pentium/mul_1.S: Rework loop to avoid AGI between update
+ of loop induction variable and load insn at beginning of loop.
+ * mpn/x86/pentium/addmul_1.S: Likewise.
+ * mpn/x86/pentium/submul_1.S: Likewise.
+
+Mon Dec 25 23:22:55 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * All files: Prefix user-visible structure fields with _mp_.
+
+Fri Dec 22 20:42:17 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/configure.in (m68k configs): Terminate path variable with
+ plain "m68k".
+
+Fri Dec 22 03:29:33 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/sparc32/add_n.S: Update from sub_n.S to fix bugs, and to
+ clean things up.
+
+ * mpn/configure.in (m68k configs): Update #include path for new
+ mpn directory organization.
+
+Tue Dec 12 02:53:02 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * gmp.h: Prefix all structure field with _mp_.
+ * gmp-impl.h: Define access macros for these fields.
+
+Sun Dec 10 00:47:17 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/alpha/addmul_1.s: Prefix labels with `.'.
+ * mpn/alpha/submul_1.s: Likewise.
+ * mpn/alpha/[lr]shift.s: Likewise.
+ * mpn/alpha/udiv_qrnnd.S: Likewise.
+ * mpn/alpha/ev5/[lr]shift.s: Likewise.
+
+ * mpn/alpha/ev5/lshift.s: Fix typos.
+
+Fri Dec 1 14:28:20 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/Makefile.in (.SUFFIXES): Define.
+
+Wed Nov 29 23:11:57 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/sparc64/{add_n.s, sub_n.s}: New files.
+
+Tue Nov 28 06:03:13 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/x86/syntax.h: Handle ELF_SYNTAX.
+ Rename GAS_SYNTAX => BSD_SYNTAX.
+
+ * mpn/configure.in: Handle linuxelf and SysV for x86 variants.
+
+Mon Nov 27 01:32:12 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/hppa/hppa1_1/pa7100/submul_1.S: New file.
+
+Sun Nov 26 04:30:47 1995 Torbjorn Granlund <tege@noisy.tmg.se>
+
+ * mpn/hppa/hppa1_1/pa7100/addmul_1.S: New file.
+
+ * mpn/sparc32/add_n.S: Rewrite to use 64 bit loads/stores.
+ * mpn/sparc32/sub_n.S: Likewise.
+
+Fri Nov 17 00:18:46 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/configure.in: Handle m68k on NextStep.
+
+Thu Nov 16 02:30:26 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn: Reorganize machine-specific directories.
+ * mpn/configure.in: Corresponding changes.
+ (sh, sh2): Handle these.
+ (m68k targets): Create asm-syntax.h.
+
+Thu Nov 9 02:20:50 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/mul_n.c (____mpn_sqr_n): Delete code that calls abort.
+ (____mpn_mul_n): Likewise.
+
+Tue Nov 7 03:25:12 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/get_str.c: In exponentiation code (two places), don't swap
+ input and output areas when calling mpn_mul_1.
+ * mpf/set_str.c: Likewise.
+
+Fri Nov 3 02:35:58 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/Makefile.in: Make sure all objects are listed in dependency list;
+ delete spurious entries.
+
+ * mpf/mul.c: Handle U or V being 0. Allow prec+1 for result precision.
+
+ * mpf/set_prec.c: New computation of limb precision.
+ * mpf/set_dfl_prec.c: Likewise.
+
+ * mpf/random2.c: Fix typo computing exp.
+ * mpf/get_str.c: In (uexp > usize) case, set n_limbs as a function of
+ the user-requested number of digits, n_digits.
+
+Thu Nov 2 16:25:07 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/divrem.c (case 2): Don't move np vector back, it is
+ never read.
+ (default case): Put most significant limb from np in new variable n2;
+ decrease size argument for MPN_COPY_DECR; use n2 instead of np[dsize].
+
+Wed Nov 1 02:59:53 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/sparc/[lr]shift.S: New files.
+
+Tue Oct 31 00:08:12 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpz/gcd_ui.c: Set w->size unconditionally when v is zero.
+
+ * gmp-impl.h (assert): Delete definition.
+
+ * mpf/sub.c: Delete all assert calls. Delete variable `cy'.
+
+ * mpf/neg.c: Use prec+1 as precision. Optimize for when arguments
+ are the same.
+ * mpf/abs.c: Likewise.
+ * mpf/{set,neg,abs}.c: Make structure and variable names similar.
+
+Mon Oct 30 12:45:26 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/random2.c (random): Test __SVR4 in addition to __svr4__.
+ * mpn/generic/random2.c (random): Likewise.
+
+Sun Oct 29 01:54:28 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/div.c: Special handle U or V being 0.
+
+ * mpf/random2.c: New file.
+
+ * longlong.h (i860 rshift_rhlc): Define.
+ (i960 udiv_qrnnd): Define.
+ (i960 count_leading_zeros): Define.
+ (i960 add_ssaaaa): Define.
+ (i960 sub_ddmmss): Define.
+ (i960 rshift_rhlc): Define.
+
+Sat Oct 28 19:09:15 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/pentium/rshift.S: Fix and generalize condition for when to use
+ special code for shift by 1.
+ * mpn/pentium/lshift.S: Likewise.
+
+Thu Oct 26 00:02:56 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * gmp.h: #undef __need_size_t.
+ * mp.h: Update from gmp.h.
+
+Wed Oct 25 00:17:27 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/Makefile.in: Compile set_prec.c.
+ * mpf/realloc.c: Delete this file.
+ * mpf/Makefile.in: Delete mentions of realloc.c.
+
+ * gmp.h (__mpf_struct): Get rid of `alloc' field.
+ * mpf/clear.c: Likewise.
+ * mpf/init*.c: Likewise.
+ * mpf/set_prec.c: Likewise.
+ * mpf/iset*.c: Likewise.
+
+ * mpf/iset_str.c: New file.
+
+ * mpn/configure.in: Handle pyramid.
+
+ * mpf/set.c: Use prec+1 as precision.
+
+ * mpf/set_prec.c: New file.
+
+Tue Oct 24 00:56:41 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/divrem.c: New file. Will replace mpn/generic/divmod.c
+ when rest of source is converted.
+ * mpn/configure.in (functions): Add `divrem'
+ * mpn/generic/set_str.c: Never call __mpn_mul_1 with zero size.
+
+ * mpf/get_str.c: Completely rewritten.
+ * mpf/add.c: Fix several problems.
+ * mpf/sub.c: Compare operands from most significant end until
+ first difference, exclude skipped limbs from computation.
+ Accordingly simplify normalization code.
+ * mpf/set_str.c: Fix several problems.
+ * mpf/dump.c: New file.
+ * mpf/Makefile.in: Compile dump.c.
+ * mpf/init2.c: Set prec field correctly.
+
+Sun Oct 22 03:02:09 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * cre-conv-tab.c: #include math.h; don't declare log and floor.
+
+Sat Oct 21 23:04:10 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/mul_ui.c: Handle U being 0.
+
+Wed Oct 18 19:39:27 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/set_str.c: Correctly handle input like "000000000000".
+ Misc cleanups.
+
+Tue Oct 17 15:14:13 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * longlong.h: Define COUNT_LEADING_ZEROS_0 for machines where
+ appropriate.
+
+Mon Oct 16 19:14:43 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/add.c: Rewrite.
+ * mpf/set_str.c: New file. Needs more work.
+
+Sat Oct 14 00:14:04 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpf/div_2exp.c: Vastly simplify.
+ * mpf/mul_2exp.c: Likewise.
+
+ * mpf/sub.c: Rewrite.
+
+ * gmp-impl.h (udiv_qrnnd_preinv2gen): Terminate comment.
+
+ * mpf/dump.c: Free allocated memory.
+
+ * gmp-impl.h (assert): Define.
+
+Wed Oct 11 13:31:00 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/pentium/rshift.S: Install new code to optimize shift-by-1.
+
+Tue Oct 10 00:37:21 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/pentium/lshift.S: Install new code to optimize shift-by-1.
+
+ * mpn/powerpc32/{lshift.s,rshift.s}: New files.
+
+ * configure.in: Fix typo.
+
+Sat Oct 7 08:17:09 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * longlong.h (smul_ppmm): Correct type of __m0 and __m1.
+
+Wed Oct 4 16:31:28 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/configure.in: Handle alphaev5.
+ * mpn/ev4: New name for alpha subdir.
+ * mpn/ev5: New subdir.
+ * mpn/ev5/lshift.s: New file.
+
+Tue Oct 3 15:06:45 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/alpha/mul_1.s: Avoid static increments of pointers; use
+ corresponding offsets in ldq and stq instructions instead.
+ (Loop): Swap cmpult and stq to save one cycle on EV5.
+
+ * mpn/tests/{add_n.s,sub_n.s,lshift.s,rshift.s,mul_1.s,addmul_1.s,
+ submul_1.s}: Don't check results if NOCHECK is defined.
+
+Mon Oct 2 11:40:18 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * longlong.h (mips umul_ppmm [32 and 64 bit versions]):
+ Make new variants, based on GCC version number, that use `l' and `h'
+ constraints instead of explicit mflo and mfhi instructions
+
+Sun Oct 1 00:17:47 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/mc88100/add_n.s: Decrease unrolling factor from 16 to 8.
+ * mpn/mc88100/sub_n.s: Likewise.
+
+ * config/mt-m88110: New file.
+ * configure.in: Use it.
+
+ * mpn/mc88110/mul_1.s: Fix thinko.
+
+Sat Sep 30 21:28:19 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpz/set_d.c: Declare `size' at function start.
+
+ * experimental: New directory for mpx and mpz2.
+
+ * mpz/tdiv_q.c: Clarify comments.
+ * mpz/{mod.c,mod_ui.c}: New file, for math mod function.
+
+ * mpn/sh2/{mul_1.s,addmul_1.s,submul_1.s}: New files.
+
+ * mpn/sh/{add_n.s,sub_n.s}: New files.
+
+ * mpn/pyr/{add_n.s,sub_n.s,mul_1.s,addmul_1.s}: New files.
+
+ * mpn/i960/{add_n.s,sub_n.s}: New files.
+
+ * mpn/alpha/addmul_1.s (Loop): Move decrement of r18 to before umulh,
+ to save cycles on EV5.
+ * mpn/alpha/submul_1.s: Ditto.
+ * mpn/alpha/mul_1.s: Ditto.
+
+Thu Sep 28 02:48:59 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * gmp.h (mp_limb, mp_limb_signed): Define as `long long' if
+ _LONG_LONG_LIMB is defined.
+
+ * longlong.h (m88110): Test __m88110__, not __mc88110__
+
+ * mpn/mc88110/mul_1.s: Rewrite.
+
+Tue Sep 26 23:29:05 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * config.sub: Update from current Cygnus version.
+
+ * mpn/configure.in: Recognize canonical m88*, not mc88*.
+
+Fri Sep 22 14:58:05 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpz/set_d.c: New file.
+ * mpz/Makefile.in: Build new files.
+
+ * mpq/get_d.c: Replace usage of scalbn with ldexp.
+
+ * mpn/{vax,i386}/gmp-mparam.h: New files.
+ * gmp-impl.h (ieee_double_extract): Define here.
+ * mpf/set_d.c (ieee_double_extract): Not here.
+
+Thu Sep 21 00:56:36 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * longlong.h (C umul_ppmm): Use UWtype, not USItype for temps.
+ (udiv_qrnnd): For cases implemented with call to __udiv_qrnnd,
+ protect with new symbol LONGLONG_STANDALONE.
+ (68000 umul_ppmm): Use %# prefix for immediate constants.
+
+Wed Sep 20 15:36:23 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/divmod_1.c: Handle
+ divisor_limb == 1 << (BITS_PER_MP_LIMB - 1)
+ specifically also when normalization_steps != 0.
+
+Mon Sep 18 15:42:30 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpq/get_d.c: New file.
+
+Sun Sep 17 02:04:36 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * longlong.h (pyr): Botch up for now.
+
+Sat Sep 16 00:11:50 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/clipper/mul_1.s: New file.
+ * mpn/clipper/add_n.s: New file.
+ * mpn/clipper/sub_n.s: New file.
+ * mpn/configure.in: Handle clipper*-*-*.
+
+ * mpn/configure.in: Recognize rs6000-*-*.
+
+Fri Sep 15 00:41:34 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/alpha/add_n.s: New file.
+ * mpn/alpha/sub_n.s: New file.
+
+ * mpn/mips3: New name for mpn/r4000.
+ * mpn/mips2: New name for mpn/r3000.
+ * mpn/configure.in: Corresponding changes.
+
+ * mpn/generic/perfsqr.c (primes): Delete.
+ (residue_map): Delete.
+
+Thu Sep 14 00:07:58 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/r3000/sub_n.s: Fix typo.
+
+ * dm_trunc.c: Delete spurious file.
+
+ * mpz/out_binary.c: Fix typo.
+
+ * mpn/configure.in (per-target): Make mips*-*-irix6* imply r4000.
+
+ * gmp-impl.h: For sparc and sgi, include alloca.h.
+
+ * mpn/z8000/mul_1.s: Replace `test r' with `and r,r'. Replace
+ `ldk r,#0' with `xor r,r'.
+
+Wed Sep 6 00:58:38 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpz/inp_binary.c: New file.
+ * mpz/out_binary.c: New file.
+ * mpz/Makefile.in: Build new files.
+
+Tue Sep 5 22:53:51 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * gmp.h (__mpz_struct): Change `long int' => `mp_size_t' for alloc
+ and size fields.
+
+Sat Sep 2 17:47:59 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/r4000/{add_n.s,sub_n.s}: Optimize away some pointer arithmetic.
+ * mpn/r3000/{add_n.s,sub_n.s,lshift.s,rshift.s}: New files,
+ derived from r4000 code.
+
+Fri Sep 1 05:35:52 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/r3000/mul_1.s: Fix typo.
+
+ * mpn/powerpc32: Fix some old vs new mnemonic issues.
+
+ * mpn/powerpc32/{add_n.s,sub_n.s}: New files.
+ * mpn/r4000/{add_n.s,sub_n.s,lshift.s,rshift.s}: New files.
+
+Wed Aug 30 10:43:47 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/r3000/mul_1.s ($LC1): Use addiu for immediate add.
+ * mpn/r4000/{mul_1.s,addmul_1.s,submul_1.s}: New files.
+
+ * config.guess: Update to latest FSF revision.
+
+Mon Aug 28 02:18:13 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpz/out_str.c: Cast str to char * in fputs call.
+
+ * gmp-impl.h: Define UQItype, SItype, and USItype also
+ when not __GNUC__.
+
+Fri Aug 25 01:45:04 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/i386/syntax.h: Renamed from asm-syntax.h.
+ * mpn/mc68020/syntax.h: Renamed from asm-syntax.h.
+ * mpn/configure.in: Corresponding changes.
+
+Sun Aug 13 19:20:04 1995 Torbjorn Granlund <tege@bozo.tmg.se>
+
+ * mpn/generic/random2.c: Test __hpux, not hpux.
+
+Sat Apr 15 20:50:33 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/sparc/add_n.S: Make it work for PIC.
+ * mpn/sparc/sub_n.s: Likewise.
+ * mpn/sparc8/addmul_1.S: Likewise.
+ * mpn/sparc8/mul_1.S: Likewise.
+ * mpn/i386/add_n.S: Likewise.
+ * mpn/i386/sub_n.S: Likewise.
+
+Thu Apr 13 23:15:03 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/configure.in: Don't search power subdir for generic ppc configs.
+ Add some ppc cpu-specific configs. Misc clean up.
+
+Mon Apr 10 00:16:35 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/ui_pow_ui.c: Delete spurious code to handle negative results.
+
+Sun Apr 9 12:38:11 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (SPARC v8 udiv_qrnnd): Generate remainder in C,
+ not in asm.
+
+ * mpn/generic/sqrt.c (SQRT): Test for __SOFT_FLOAT.
+
+Tue Mar 28 00:19:52 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/hamdist.c (popc_limb): Make Mar 16 change here too.
+
+Fri Mar 17 23:29:22 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (SH umul_ppmm): Define.
+
+Thu Mar 16 16:40:44 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/popcount.c (popc_limb): Rearrange 32 bit case
+ to help CSE.
+
+Fri Mar 10 20:03:49 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/powerpc32/mul_1.s: Clear cy before entering loop.
+ Rearrange loop to save a cycle.
+ * mpn/powerpc32/addmul_1.s: New file.
+ * mpn/powerpc32/submul_1.s: New file.
+
+Fri Feb 17 22:44:45 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/configure.in: Set target_makefile_frag for freebsd
+ in new case stmt.
+ * mpn/config/t-freebsd: New file.
+ * mpn/Makefile.in: Add #### for frag insertion.
+ (XCFLAGS): Clear by default.
+ (.c.o, .S.o rules): Pass XCFLAGS.
+
+Tue Feb 7 16:27:50 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (68000 umul_ppmm): Merge improvements from henderson.
+
+Tue Jan 24 04:23:20 1995 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h (default umul_ppmm): Store input parameters in temporaries
+ to avoid reading them twice.
+ (default smul_ppmm): New definition.
+
+Thu Dec 29 04:20:07 1994 Jim Meyering (meyering@comco.com)
+
+ * generic/perfsqr.c (__mpn_perfect_square_p): Remove declaration
+ of unused variable.
+ * generic/pre_mod_1.c (__mpn_preinv_mod_1): Likewise.
+ * mpz/powm.c (pow): Likewise.
+
+ * mpz/and.c (mpz_and): Use {} instead of `;' for empty else clause
+ to placate `gcc -Wall'.
+ * mpz/ior.c (mpz_ior): Likewise.
+
+Wed Dec 28 13:31:40 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/m*68*/*.S: #include asm-syntax.h, not asm.h.
+
+Mon Dec 26 17:15:36 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * longlong.h: Test for more symbols, in __mc68000__ case.
+
+ * mpn/mpn/config.sub: Recognize m68060.
+ * mpn/configure.in: Change mc* to m* for 68k targets.
+ * mpn/Makefile.in (.S.o): Delete spurious creation of temp .c file.
+
+Mon Dec 19 01:56:30 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * config.sub: Recognize pentium as a valid CPU.
+ * mpn/configure.in: Handle pentium specifically, to use new assembly
+ code.
+
+Mon Dec 19 00:13:01 1994 Jim Meyering (meyering@comco.com)
+
+ * gmp.h: Define _GMP_H_HAVE_FILE if FILE, __STDIO_H__, or H_STDIO
+ is defined.
+ * gmp.h: test _GMP_H_HAVE_FILE instead of FILE everywhere else.
+
+Mon Dec 19 00:04:54 1994 Kent Boortz (boortz@sics.se)
+
+ * Makefile.in (recursive makes): Pass CFLAGS.
+
+Sun Dec 18 22:34:49 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/pentium: New directory.
+
+ * mpz/pprime.c: Make sure to mpz_clear all temporaries.
+
+ * longlong.h: Don't use udiv instruction when SUPERSPARC is defined.
+ * configure.in: Handle supersparc*-.
+ * config/mt-supspc-gcc: New file.
+ * config/mt-sparc8-gcc: New name for mt-sparcv8-gcc.
+
+Mon Dec 12 22:22:10 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/i386/*.S: #include "asm-syntax.h", not "asm.h".
+ #include sysdep.h before asm-syntax.h.
+
+ * mpn/mc68020/asm-syntax.h: #undef ALIGN before defining it.
+ * mpn/i386/asm-syntax.h: Likewise.
+
+ * mpn/mc68020/asm-syntax.h: New name for asm.h.
+ * mpn/i386/asm-syntax.h: New name for asm.h.
+
+Tue Dec 6 21:55:25 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/array_init.c: Fix typo in declaration.
+
+Fri Nov 18 19:50:52 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/Makefile.in (.S.o): Pass CFLAGS and INCLUDES.
+
+Mon Nov 14 00:34:12 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/generic/random2.c (random): Test for __svr4__.
+
+Wed Oct 12 23:28:16 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * cre-conv-tab.c (main): Avoid upper-case X in printf format string.
+
+Tue Aug 23 17:16:35 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/perfsqr.c: Use mpn_perfect_square_p.
+ * mpn/generic/perfsqr.c: New file.
+
+Wed Jul 6 13:46:51 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/array_init.c: New file.
+ * mpz/Makefile.in: Compile array_init.
+ * gmp.h: Declare mpz_array_init.
+
+Mon Jul 4 01:10:03 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/add.c: Fix bogus comment.
+ * mpz/sub.c: Likewise.
+
+Sat Jul 2 02:14:56 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/generic/pre_mod_1.c: New file.
+ * mpz/perfsqr.c: Use __mpn_preinv_mod_1 when faster.
+
+Fri Jul 01 22:10:19 1994 Richard Earnshaw (rwe11@cl.cam.ac.uk)
+
+ * longlong.h (arm umul_ppmm): Fix typos in last change. Mark
+ hard-coded registers with "%|"
+
+Thu Jun 30 03:59:33 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpz/perfsqr.c: Define PP, etc, for machines with 64 bit limbs.
+ Use __mpn_mod_1.
+ * mpz/perfsqr.c: Don't clobber REM in quadratic residue check loop.
+
+Wed Jun 29 18:45:41 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/generic/sqrt.c (SQRT): New asm for IBM POWER2.
+
+ * mpz/gcd_ui.c: Return 0 if result does not fit an unsigned long.
+
+ * gmp.h: Use "defined (__STDC__)" consistently.
+
+Tue Jun 28 18:44:58 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * gmp.h (mpz_get_si): Don't use "signed" keyword for return type.
+
+ * mpz/tests/Makefile.in: Use CFLAGS for linking.
+
+ * Makefile.in (CFLAGS): Use -O2 here.
+ * mpn/Makefile (CFLAGS): Not here.
+
+ * mpq/cmp_ui.c: Fix typo.
+ * mpq/canonicalize.c: Fix typo.
+ * mpz/gcd_ui.c: Handle gcd(0,v) and gcd(u,0) correctly.
+ * mpn/generic/gcd_1.c: Fix braino in last change.
+
+Mon Jun 27 16:10:27 1994 Torbjorn Granlund (tege@rtl.cygnus.com)
+
+ * mpz/gcd_ui.c: Change return type and return result.
+ Allow destination param to be NULL.
+ * gmp.h: Corresponding change.
+ * mpn/generic/gcd_1.c: Handle zero return from mpn_mod_1.
+
+Tue Jun 14 02:17:43 1994 Torbjorn Granlund (tege@tiny.cygnus.com)
+
+ * mpn/i386/asm.h (ALIGN): Make it take a parameter.
+ * mpn/i386/*.S: Use ALIGN to align all loops.
+
+ * mpn/i386/*.S: Move colon inside C_GLOBAL_NAME expression.
+ (Makes old versions of GAS happy.)
+
+Sat May 28 01:43:54 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * Many files: Delete unused variables and labels.
+ * mpn/generic/dump.c: cast printf width argument to int.
+
+Wed May 25 00:42:37 1994 Torbjorn Granlund (tege@thepub.cygnus.com)
+
+ * mpz/gcd.c (mpz_gcd): Normalize after __mpn_sub calls.
+ (xmod): Ignore return value of __mpn_divmod.
+ (xmod): Improve normalization code.
+
+Sat May 21 01:30:09 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/gcdext.c: Cosmetic changes.
+
+ * mpz/fdiv_ui.c: New file.
+
+Fri May 20 00:24:53 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/tests/Makefile.in: Use explicit rules for running tests,
+ not a shell loop.
+ (clean): Delete stmp-*.
+
+ * mpz/Makefile.in: Update.
+
+ * mpz/div_ui.c: Don't include longlong.h.
+ * mpz/dm_ui.c: Likewise.
+
+ * mpz/fdiv_q.c, mpz/fdiv_q_ui.c, mpz/fdiv_qr.c, mpz/fdiv_qr_ui.c,
+ mpz/fdiv_r.c, mpz/fdiv_r_ui.c: New files. Code partly from deleted
+ mdm.c, mdm_ui.c, etc, partly rewritten.
+ * mpz/dm_floor_ui.c, mpz/dm_floor.c: Delete.
+ * mpz/mdm.c, mpz/mdm_ui.c, mpz/mdiv.c, mpz/mdiv_ui.c, mpz/mmod.c,
+ mpz/mmod_ui.c: Delete.
+
+ * mpz/tdiv_q.c, mpz/tdiv_q_ui.c, mpz/tdiv_qr.c, mpz/tdiv_qr_ui.c,
+ mpz/tdiv_r.c, mpz/tdiv_r_ui.c:
+ New names for files implementing truncating division.
+ * mpz/div_ui.c, mpz/dm_ui.c, mpz/mod_ui.c: Simplify.
+
+ * mpn/Makefile.in (.S.o): Don't rely on CPP being defined, use CC
+ instead.
+ (clean): Delete tmp-*.
+
+Thu May 19 01:37:44 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/cmp.c: Call __mpn_cmp.
+
+ * mpz/popcount.c: Fix typo.
+
+ * mpz/powm_ui.c: Simplify main loop. Keep principal operand size
+ smaller than MSIZE when possible.
+ * mpz/powm.c: Likewise.
+
+ * mpn/generic/sqrt.c: Move alloca calls into where the memory is
+ needed. Simplify.
+
+ * gmp.h: (_PROTO): New macro.
+ Add many function declarations; use _PROTO macro in all declarations.
+
+ * mpf/*.c: Prepend mpn calls with __.
+
+Wed May 18 20:57:06 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpf/*ui*.c: Make ui argument `long' for consistency with mpz
+ functions.
+
+ * mpf/div_ui.c: Simplify.
+
+Tue May 17 01:05:14 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/*.c: Prepend mpn calls with __.
+
+ * mpz/mul_ui.c: Use mpn_mul_1.
+
+Mon May 16 17:19:41 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpn/i386/mul_1.S: Use C_GLOBAL_NAME.
+ * mpn/i386/mul_1.S, mpn/i386/addmul_1.S, mpn/i386/submul_1.S:
+ Nuke use of LAB.
+
+Sat May 14 14:21:02 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * gmp-impl.h: Don't define abort here.
+
+ * mpz/pow_ui.c: Increase temporary allocation.
+ * mpz/ui_pow_ui.c: Likewise.
+
+ * gmp.h (mpz_add_1, mpz_sub_1): Don't call memcpy.
+
+ * All Makefile.in: Delete spurious -I arguments.
+ Update dependencies.
+
+ * mpz/popcount.c: New file.
+ * mpz/hamdist.c: New file.
+
+ * All configure: Latest version from Cygnus.
+
+ * mpq/Makefile.in: New file.
+ * mpq/configure.in: New file.
+ * Makefile.in, configure.in: Enable compilation of mpq.
+
+ * mpq/set_z.c: Fix typos.
+ * mpq/canonicalize.c: Fix typos.
+ * mpq/cmp_ui.c: Fix typos.
+
+ * mpf/add_ui.c: Read U->D into UP always. Delete spurious MPN_COPY.
+ * mpf/sub_ui.c: Likewise.
+
+ * gmp-impl.h: Don't redefine alloca.
+
+ * COPYING.LIB: Renamed from COPYING.
+
+Wed May 11 01:45:44 1994 Torbjorn Granlund (tege@adder.cygnus.com)
+
+ * mpz/powm_ui.c: When shifting E left by C+1, handle out-of-range
+ shift counts. Fix typo when testing negative_result.
+ * mpz/powm.c: Likewise.
+
+ * mpz/ui_pow_ui.c: New file.
+ * mpz/Makefile.in: Update.
+
+ * mpz/pow_ui.c: Call __mpn_mul_n instead of __mpn_mul when possible.
+
+ * mpz/div.c, mpz/div_ui.c, mpz/gcd.c: Prefix external mpn calls.
+ * mpz/gcd.c: Declare mpn_xmod.
+
+ * mpz/powm.c: Major changes to accommodate changed mpn semantics.
+ * mpz/powm_ui.c: Update from mpz/powm.c.
+
+ * mpz/tests/tst-io.c: New file.
+ * mpz/tests/tst-logic: New file.
+ * mpz/tests/Makefile.in: Update.
+
+ * mpz/inp_str.c: Get base right when checking for first digit.
+ * mpz/inp_str.c: Allocate more space for DEST when needed.
+
+ * mpz/com.c: Use mpn_add_1 and mpn_sub_1.
+ * mpz/and.c, mpz/ior.c: Likewise. Simplify somewhat.
+
+ * mpz/add_ui.c: Use mpn_add_1 and mpn_sub_1.
+ Rename parameters to be consistent with mpz/sub_ui.
+ General simplifications.
+ * mpz/sub_ui.x: Likewise.
+
+Tue Aug 10 19:41:16 1993 Torbjorn Granlund (tege@prudens.matematik.su.se)
+
+ * mpf: New directory.
+ * mpf/*.c: Merge basic set of mpf functions.
+
+ * Many logs missing...
+
+Sun Apr 25 18:40:26 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * memory.c: Use #if instead of #ifdef for __STDC__ for consistency.
+ * bsd/xtom.c: Likewise.
+
+ * mpz/div.c: Remove free_me and free_me_size and their usage.
+ Use mpn_divmod for division; corresponding changes in return value
+ convention.
+ * mpz/powm.c: `carry_digit' => `carry_limb'.
+ * bsd/sdiv.c: Clearify comment.
+
+Sun Apr 25 00:31:28 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * longlong.h (__udiv_qrnnd_c): Make all variables `unsigned long int'.
+
+Sat Apr 24 16:23:33 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * longlong.h (__udiv_qrnnd_c): Make all variables `unsigned long int'.
+
+ * gmp-impl.h: #define ABS.
+ * (Many files): Use ABS instead of abs.
+
+ * mpn/generic/sqrt.c, mpz/clrbit.c, mpz/get_si.c, mpz/mod_2exp.c,
+ mpz/pow_ui.c: Cast 1 to mp_limb before shifting.
+
+ * mpz/perfsqr.c: Use #if, not plain if for exclusion of code for
+ non-32-bit machines.
+
+Tue Apr 20 13:13:58 1993 Torbjorn Granlund (tege@du.nada.kth.se)
+
+ * mpn/generic/sqrt.c: Handle overflow for intermediate quotients by
+ rounding them down to fit.
+
+ * mpz/perfsqr.c (PP): Define in hexadecimal to avoid GCC warnings.
+
+ * mpz/inp_str.c (char_ok_for_base): New function.
+ (mpz_inp_str): Use it.
+
+Sun Mar 28 21:54:06 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/inp_raw.c: Allocate x_index, not xsize limbs.
+
+Mon Mar 15 11:44:06 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * mpz/pprime.c: Declare param `const'.
+ * gmp.h: Add declarations for mpz_com.
+
+Thu Feb 18 14:10:34 1993 Torbjorn Granlund (tege@pde.nada.kth.se)
+
+ * mpq/add.c, mpq/sub.c: Call mpz_clear for t.
+
+Fri Feb 12 20:27:34 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/inp_str.c: Recog minus sign as first character.
+
+Wed Feb 3 01:36:02 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/iset.c: Handle 0 size.
+
+Tue Feb 2 13:03:33 1993 Torbjorn Granlund (tege@cyklop.nada.kth.se)
+
+ * mpz/mod_ui.c: Initialize dividend_size before it's used.
+
+Mon Jan 4 09:11:15 1993 Torbjorn Granlund (tege@sics.se)
+
+ * bsd/itom.c: Declare param explicitly 'signed'.
+ * bsd/sdiv.c: Likewise.
+
+ * mpq/cmp.c: Remove unused variable tmp_size.
+ * mpz/powm_ui.c: Fix typo in esize==0 if stmt.
+ * mpz/powm.c: Likewise.
+
+Sun Nov 29 01:16:11 1992 Torbjorn Granlund (tege@sics.se)
+
+ * mpn/generic/divmod_1.c (mpn_divmod_1): Handle
+ divisor_limb == 1 << (BITS_PER_MP_LIMB - 1)
+ specifically.
+
+ * Reorganize sources. New directories mpn, mpn/MACH, mpn/generic,
+ mpz, mpq, bsd. Use full file name for change logs hereafter.
+
+Wed Oct 28 17:40:04 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * longlong.h (__hppa umul_ppmm): Fix typos.
+ (__hppa sub_ddmmss): Swap input arguments.
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Avoid , before } in
+ initializator.
+
+Sun Oct 25 20:30:06 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * mpz_pprime.c (mpz_probab_prime_p): Handle numbers <= 3
+ specifically (used to consider all negative numbers prime).
+
+ * mpz_powm_ui: `carry_digit' => `carry_limb'.
+
+ * sdiv: Handle zero dividend specifically. Replace most code in
+ this function with a call to mpn_divmod_1.
+
+Fri Sep 11 22:15:55 1992 Torbjorn Granlund (tege@tarrega.sics.se)
+
+ * mpq_clear: Don't free the MP_RAT!
+
+ * mpn_lshift, mpn_rshift, mpn_rshiftci: Remove `long' from 4:th arg.
+
+Thu Sep 3 01:47:07 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * All files: Remove leading _ from mpn function names.
+
+Wed Sep 2 22:21:16 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ Fix from Jan-Hein Buhrman:
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c: Make them work as documented.
+
+ * mpz_mmod.c, mpz_mdm.c: Move decl of TEMP_DIVISOR to reflect its
+ life.
+
+Sun Aug 30 18:37:15 1992 Torbjorn Granlund (tege@jupiter.sics.se)
+
+ * _mpz_get_str: Use mpz_sizeinbase for computing out_len.
+ * _mpz_get_str: Don't remove leading zeros. Abort if there are some.
+
+Wed Mar 4 17:56:56 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h: Change definition of MP_INT to make the & before params
+ optional. Use typedef to define it.
+ * mp.h: Use typedef to define MINT.
+
+Tue Feb 18 14:38:39 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ longlong.h (hppa umul_ppmm): Add missing semicolon. Declare type
+ of __w1 and __w0.
+
+Fri Feb 14 21:33:21 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Make default count_leading_zeros work for machines >
+ 32 bits. Prepend `__' before local variables to avoid conflicts
+ with users' variables.
+
+ * mpn_dm_1.c: Remove udiv_qrnnd_preinv ...
+ * gmp-impl.h: ... and put it here.
+ * mpn_mod_1: Use udiv_qrnnd_preinv if it is faster than udiv_qrnnd.
+
+Tue Feb 11 17:20:12 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Enhance base case by handling small multiplicands.
+ * mpn_dm_1.c: Revert last change.
+
+Mon Feb 10 11:55:15 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_dm_1.c: Don't define udiv_qrnnd_preinv unless needed.
+
+Fri Feb 7 16:26:16 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Replace code for base case.
+
+Thu Feb 6 15:10:42 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_dm_1.c (_mpn_divmod_1): Add code for avoiding division by
+ pre-inverting divisor.
+
+Sun Feb 2 11:10:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Make __LLDEBUG__ work differently.
+ (_IBMR2): Reinsert old code.
+
+Sat Feb 1 16:43:00 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (#ifdef _IBMR2): Replace udiv_qrnnd with new code
+ using floating point operations. Don't define
+ UDIV_NEEDS_NORMALIZATION any longer.
+
+Fri Jan 31 15:09:13 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Define UMUL_TIME and UDIV_TIME for most machines.
+ * longlong.h (#ifdef __hppa): Define umul_ppmm.
+
+Wed Jan 29 16:41:36 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_cmp: Only one length parameter, assume operand lengths are
+ the same. Don't require normalization.
+ * mpq_cmp, mpz_add, mpz_sub, mpz_gcd, mpn_mul, mpn_sqrt: Change for
+ new mpn_cmp definition.
+
+Tue Jan 28 11:18:55 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str: Fix typo in comment.
+
+Mon Jan 27 09:44:16 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Makefile.in: Add new files.
+
+ * mpn_dm_1.c: New file with function _mpn_divmod_1.
+ * mpz_dm_ui.c (mpz_divmod_ui): Use _mpn_divmod_1.
+ * mpz_div_ui: Likewise.
+
+ * mpn_mod_1.c: New file with function _mpn_mod_1.
+ * mpz_mod_ui: Use _mpn_mod_1.
+
+Thu Jan 23 18:54:09 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Bug found by Paul Zimmermann (zimmermann@inria.inria.fr):
+ * mpz_div_ui.c (mpz_div_ui), mpz_dm_ui.c (mpz_divmod_ui):
+ Handle dividend == 0.
+
+Wed Jan 22 12:02:26 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_pprime.c: Use "" for #include.
+
+Sun Jan 19 13:36:55 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshiftci.c (header): Correct comment.
+
+Wed Jan 15 18:56:04 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_powm, mpz_powm_ui (if (bsize > msize)): Do alloca (bsize + 1)
+ to make space for ignored quotient at the end. (The quotient might
+ always be an extra limb.)
+
+Tue Jan 14 21:28:48 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_powm_ui: Fix comment.
+ * mpz_powm: Likewise.
+
+Mon Jan 13 18:16:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * tests/Makefile.in: Prepend $(TEST_PREFIX) to Makefile target.
+
+Sun Jan 12 13:54:28 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Fixes from Kazumaro Aoki:
+ * mpz_out_raw: Take abs of size to handle negative values.
+ * mpz_inp_raw: Reallocate before reading ptr from X.
+ * mpz_inp_raw: Store, don't read, size to x->size.
+
+Tue Jan 7 17:50:25 1992 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h, mp.h: Remove parameter names from prototypes.
+
+Sun Dec 15 00:09:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * tests/Makefile.in: Prepend "./" to file names when executing
+ tests.
+
+ * Makefile.in: Fix many problems.
+
+Sat Dec 14 01:00:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_sqrt.c: New file with _mpn_sqrt.
+ * mpz_sqrt, mpz_sqrtrem, mpz_perfect_square_p: Use _mpn_sqrt.
+ * msqrt.c: Delete. Create from mpz_sqrtrem.c in Makefile.in.
+ * mpz_do_sqrt.c: Delete.
+ * Makefile.in: Update to reflect these changes.
+
+ * Makefile.in, configure, configure.subr: New files
+ (from bothner@cygnus.com).
+ * dist-Makefile: Delete.
+
+ * mpz_fac_ui: Fix comment.
+
+ * mpz_random2: Rewrite a bit to make it possible for the most
+ significant limb to be == 1.
+
+ * mpz_pprime.c (mpz_probab_prime_p): Remove \t\n.
+
+Fri Dec 13 23:10:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_do_sqrt: Simplify special case for U == 0.
+ * m*sqrt*.c, mpz_perfsqr.c (mpz_perfect_square_p):
+ Rename _mpz_impl_sqrt to _mpz_do_sqrt.
+
+Fri Dec 13 12:52:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp-impl.h (MPZ_TMP_INIT): Cast to the right type.
+
+Thu Dec 12 22:17:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_add, mpn_sub, mpn_mul, mpn_div: Change type of several
+ variables to mp_size.
+
+Wed Dec 11 22:00:34 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshift.c: Fix header comments.
+
+Mon Dec 9 17:46:10 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.2.
+
+ * gmp-impl.h (MPZ_TMP_INIT): Cast alloca return value.
+
+ * dist-Makefile: Add missing dependency for cre-mparam.
+
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c, mpz_mdiv_ui.c,
+ mpz_mmod_ui.c, mpz_mdm_ui.c: Remove obsolete comment.
+
+ * dist-Makefile (clean): clean in tests subdir too.
+ * tests/Makefile: Define default values for ROOT and SUB.
+
+ * longlong.h (__a29k__ udiv_qrnnd): Change "q" to "1" for operand
+ 2 constraint.
+
+Mon Nov 11 00:06:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_sizeinb.c (mpz_sizeinbase): Special code for size == 0.
+
+Sat Nov 9 23:47:38 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.1.94.
+
+ * dist-Makefile, Makefile, tests/Makefile: Merge tests into
+ distribution.
+
+Fri Nov 8 22:57:19 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h: Don't use keyword `signed' for non-ANSI compilers.
+
+Thu Nov 7 22:06:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Cosmetic changes to keep it identical to gcc2 version
+ of longlong.h.
+ * longlong.h (__ibm032__): Fix operand order for add_ssaaaa and
+ sub_ddmmss.
+
+Mon Nov 4 00:36:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Fix indentation.
+
+ * mpz_do_sqrt: Don't assume 32 bit limbs (had constant
+ 4294967296.0).
+ * mpz_do_sqrt: Handle overflow in conversion from double returned
+ by SQRT to mp_limb.
+
+ * gmp.h: Add missing function definitions.
+
+Sun Nov 3 18:25:25 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_pow_ui: Change type of `i' to int.
+
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+ * ChangeLog: Add change log entry.
+Stack overflow.
+
+ * mpz_pow_ui.c: Fix typo in comment.
+
+ * dist-Makefile: Create rpow.c from mpz_powm_ui.c.
+ * mpz_powm_ui.c: Add code for rpow.
+ * rpow.c: Delete this file. The rpow function is now implemented
+ in mpz_powm_ui.c.
+
+ * mpz_fac_ui.c: New file.
+ * gmp.h, dist-Makefile: Add stuff for mpz_fac_ui.
+
+ Bug found by John Amanatides (amana@sasquatch.cs.yorku.ca):
+ * mpz_powm_ui, mpz_powm: Call _mpn_mul in the right way, with
+ the first argument not smaller than the second.
+
+Tue Oct 29 13:56:55 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main), cre-mparam.c (main): Fix typo in output
+ header text.
+
+Mon Oct 28 00:35:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random2: Handle size == 0.
+
+ * gmp-impl.h (struct __mp_bases): Rename chars_per_limb_exactly to
+ chars_per_bit_exactly, and change its definition.
+ * cre-conv-tab.c (main): Output field according to its new
+ definition.
+ * mpz_out_str, _mpz_get_str, mpz_sizeinb, mout:
+ Use chars_per_bit_exactly.
+
+ * mpz_random2: Change the loop termination condition in order to
+ get a large most significant limb with higher probability.
+
+ * gmp.h: Add declaration of new mpz_random2 and mpz_get_si.
+ * mpz_get_si.c: New file.
+ * dist-Makefile: Add mpz_random2 and mpz_get_si.
+
+ * mpz_sizeinb.c (mpz_sizeinbase): Special code for base being a
+ power of 2, giving exact result.
+
+ * mpn_mul: Fix MPN_MUL_VERIFY in various ways.
+ * mpn_mul: New macro KARATSUBA_THRESHOLD.
+ * mpn_mul (karatsuba's algorithm): Don't write intermediate results
+ to prodp, use temporary pp instead. (Intermediate results can be
+ larger than the final result, possibly writing into hyperspace.)
+ * mpn_mul: Make smarter choice between Karatsuba's algorithm and the
+ shortcut algorithm.
+ * mpn_mul: Fix typo, cy instead of xcy. Unify carry handling code.
+
+Sun Oct 27 19:57:32 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: In non-classical case, choose Karatsuba's algorithm only
+ when usize > 1.5 vsize.
+
+ * mpn_mul: Break between classical and Karatsuba's algorithm at
+ KARATSUBA_THRESHOLD, if defined. Default to 8.
+
+ * mpn_div: Kludge to fix stray memory read.
+
+Sat Oct 26 20:06:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext: Handle a = b = 0. Remove memory leakage by calling
+ mpz_clear for all temporary variables.
+
+ * mpz_gcd: Reduce w_bcnt in _mpn_lshift call to hold that
+ function's argument constraints. Compute wsize correctly.
+
+ * mpz_gcd: Fix typo in comment.
+
+ * memory.c (_mp_default_allocate, _mp_default_reallocate): Call
+ abort if allocation fails, don't just exit.
+
+Fri Oct 25 22:17:20 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random2.c: New file.
+
+Thu Oct 17 18:06:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Bugs found by Pierre-Joseph Gailly (pjg@sunbim.be):
+ * mpq_cmp: Take sign into account, don't just compare the
+ magnitudes.
+ * mpq_cmp: Call _mpn_mul in the right way, with the first argument
+ not smaller than the second.
+
+Wed Oct 16 19:27:32 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_random: Ensure the result is normalized.
+
+Tue Oct 15 14:55:13 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_clrbit: Support non-ANSI compilers.
+
+Wed Oct 9 18:03:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (68k add_ssaaaa, sub_ddmmss): Generalize constraints.
+
+Tue Oct 8 17:42:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mdm_ui: Add comments.
+
+ * mpz_mdiv: Use MPZ_TMP_INIT instead of mpz_init.
+ * mpz_init_ui: Change spacing and header comment.
+
+Thu Oct 3 18:36:13 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile: Prepend `./' before some filenames.
+
+Sun Sep 29 14:02:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.1 (public).
+
+ * mpz_com: New name of mpz_not.
+ * dist-Makefile: Change mpz_not to mpz_com.
+
+Tue Sep 24 12:44:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Fix header comment.
+
+Mon Sep 9 15:16:24 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0.92.
+
+ * mpn_mul.c (_mpn_mul): Handle leading zero limbs in non-Karatsuba
+ case.
+
+ * longlong.h (m68000 umul_ppmm): Clobber one register less by
+ slightly rearranging the code.
+
+Sun Sep 1 18:53:25 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (stamp-stddefh): Fix typo.
+
+Sat Aug 31 20:41:31 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0.91.
+
+ * mpz_mdiv.c, mpz_mmod.c, mpz_mdm.c, mpz_mdiv_ui.c,
+ mpz_mmod_ui.c, mpz_mdm_ui.c: New files and functions.
+ * gmp.h, gmp.texi: Define the new functions.
+
+Fri Aug 30 08:32:56 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext: Compute t argument from the other quantities at the
+ end, of the function, not in the loop. New feature: Allow t to be
+ NULL.
+
+ * mpz_add.c, mpz_sub.c, mpz_mul.c, mpz_powm.c, mpz_gcd.c: Don't
+ include "mp.h". Use type name `MP_INT' always.
+
+ * dist-Makefile, mpz_cmp.c: Merge mcmp.c from mpz_cmp.c.
+
+Wed Aug 28 00:45:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (documentation): Go via tmp.texi to avoid the
+ creation of gmp.dvi if any errors occur. Make tex read input
+ from /dev/null.
+
+Fri Aug 23 15:58:52 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (68020, i386): Don't define machine-dependent
+ __umulsidi3 (so the default definition is used).
+ * longlong.h (all machines): Cast all operands, sources and
+ destinations, to `unsigned long int'.
+ * longlong.h: Add gmicro support.
+
+Thu Aug 22 00:28:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Rename BITS_PER_LONG to LONG_TYPE_SIZE.
+ * longlong.h (__ibm032__): Define count_leading_zeros and umul_ppmm.
+ * longlong.h: Define UMUL_TIME and UDIV_TIME for some CPUs.
+ * _mpz_get_str.c: Add code to do division by big_base using only
+ umul_qrnnd, if that is faster. Use UMUL_TIME and UDIV_TIME to
+ decide which variant to use.
+
+Wed Aug 21 15:45:23 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (__sparc__ umul_ppmm): Move two insn from end to the
+ nops. (Saves two insn.)
+
+ * longlong.h (__sparc__ umul_ppmm): Rewrite in order to avoid
+ branch, and to permit input/output register overlap.
+
+ * longlong.h (__29k__): Remove duplicated udiv_qrnnd definition.
+ * longlong.h (__29k__ umul_ppmm): Split asm instructions into two
+ asm statements (gives better code if either the upper or lower
+ part of the product is unused.
+
+Tue Aug 20 17:57:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str.c (outside of functions): Remove
+ num_to_ascii_lower_case and num_to_ascii_upper_case. Use string
+ constants in the function instead.
+
+Mon Aug 19 00:37:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main): Output table in hex. Output 4 fields, not
+ 3, for components 0 and 1.
+
+ * gmp.h: Add declaration of mpq_neg.
+
+ Released 1.0beta.13.
+
+ * _mpz_set_str.c (mpz_set_str): Cast EOF and SPC to char before
+ comparing to enum literals SPC and EOF. This makes the code work
+ for compilers where `char' is unsigned. (Bug found by Brian
+ Beuning).
+
+ Released 1.0beta.12.
+
+ * mpz_mod_ui: Remove references to quot. Remove quot_ptr, quot_size
+ declarations and assignment code.
+
+Sun Aug 18 14:44:26 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mod_ui: Handle dividend < 0.
+
+ Released 1.0beta.11.
+
+ * mpz_dm_ui, mpz_div_ui, mpz_mod_ui, sdiv: Make them share the same
+ general structure, variable names, etc.
+
+ * sdiv: Un-normalize the remainder in n1 before it is negated.
+
+ * longlong.h: Mention UDIV_NEEDS_NORMALIZATION in description of
+ udiv_qrnnd.
+
+ * mpz_dm_ui.c (mpz_divmod_ui), mpz_div_ui.c (mpz_div_ui): Increment
+ the quotient size if the dividend size is incremented. (Bug found
+ by Brian Beuning.)
+
+ * mpz_mod_ui: Shift back the remainder, if UDIV_NEEDS_NORMALIZATION.
+ (Bug found by Brian Beuning.)
+
+ * mpz_mod_ui: Replace "digit" by "limb".
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Disable second test case
+ for non-32-bit machines (PP is hardwired for such machines).
+ * mpz_perfsqr.c (outside of functions): Define PP value with an L.
+
+ * mpn_mul.c (_mpn_mul): Add verification code that is activated if
+ DEBUG is defined. Replace "digit" by "limb".
+ * mpn_mul.c (_mpn_mul: Karatsuba's algorithm: 4.): Normalize temp
+ after the addition.
+ * mpn_mul.c (_mpn_mul: Karatsuba's algorithm: 1.): Compare u0_size
+ and v0_size, and according to the result, swap arguments in
+ recursive call. (Don't violate mpn_mul's own argument
+ constraints.)
+
+Fri Aug 16 13:47:12 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0beta.10.
+
+ * longlong.h (IBMR2): Add udiv_qrnnd.
+
+ * mpz_perfsqr: Remove unused variables.
+
+ * mpz_and (case for different signs): Initialize loop variable i!
+
+ * dist-Makefile: Update automatically generated dependencies.
+ * dist-Makefile (madd.c, msub.c, pow.c, mult.c, gcd.c): Add mp.h,
+ etc to dependency file lists.
+
+ * longlong.h (add_ssaaaa, sub_ddmmss [C default versions]): Make __x
+ `unsigned long int'.
+ * longlong.h: Add `int' after `unsigned' and `long' everywhere.
+
+Wed Aug 14 18:06:48 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Add ARM, i860 support.
+
+ * mpn_lshift, mpn_rshift, mpn_rshiftci: Rename *_word with *_limb.
+
+Tue Aug 13 21:57:43 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str.c, _mpz_set_str.c, mpz_sizeinb.c (mpz_sizeinbase),
+ mpz_out_str.c, mout.c: Remove declaration of __mp_bases.
+ * gmp-impl.h: Put it here, and make it `const'.
+ * cre-conv-tab.c (main): Make struct __mp_bases `const'.
+
+Mon Aug 12 17:11:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * cre-conv-tab.c (main): Use %lu in printf for long ints.
+
+ * dist-Makefile: Fix cre-* dependencies.
+
+ * cre-conv-tab.c (main): Output field big_base_inverted.
+
+ * gmp-impl.h (struct bases): New field big_base_inverted.
+ * gmp-impl.h (struct bases): Change type of chars_per_limb_exactly
+ to float (in order to keep the structure smaller).
+
+ * mp.h, gmp.h: Change names of macros for avoiding multiple
+ includes.
+
+Fri Aug 9 18:01:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_get_str: Only shift limb array if normalization_steps != 0
+ (optimization).
+
+ * longlong.h (sparc umul_ppmm): Use __asm__, not asm.
+ * longlong.h (IBMR2 umul_ppmm): Refer to __m0 and __m1, not to m0
+ and m1 (overlap between output and input operands did not work).
+ * longlong.h: Add VAX, ROMP and HP-PA support.
+ * longlong.h: Sort the machine dependent code in alphabetical order
+ on the CPU name.
+ * longlong.h: Hack comments.
+
+Thu Aug 8 14:13:36 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ Released 1.0beta.9.
+
+ * longlong.h: Define BITS_PER_LONG to 32 if it's not already
+ defined.
+ * Define __BITS4 to BITS_PER_LONG / 4.
+ * Don't assume 32 bit word size in "count_leading_zeros" C macro.
+ Use __BITS4 and BITS_PER_LONG instead.
+
+ * longlong.h: Don't #undef internal macros (reverse change of Aug 3).
+
+ * longlong.h (68k): Define add_ssaaaa sub_ddmmss, and umul_ppmm
+ even for plain mc68000.
+
+ * mpq_div: Flip the sign of the numerator *and* denominator of the
+ result if the intermediate denominator is negative.
+
+ * mpz_and.c, mpz_ior.c: Use MPN_COPY for all copying operations.
+
+ * mpz_and.c: Compute the result size more conservatively.
+ * mpz_ior.c: Likewise.
+
+ * mpz_realloc: Never allocate zero space even if NEW_SIZE == 0.
+
+ * dist-Makefile: Remove madd.c, msub.c, pow.c, mult.c, gcd.c from
+ BSDMP_SRCS.
+
+ * dist-Makefile: Create mult.c from mpz_mul.c.
+ * mult.c: Delete this file.
+
+ * _mpz_set_str: Normalize the result (for bases 2, 4, 8... it was
+ not done properly if the input string had many leading zeros).
+
+Sun Aug 4 16:54:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * dist-Makefile (gcd.c, pow.c, madd.c, msub.c): Make these targets
+ work with VPATH and GNU MP.
+
+ * mpz_gcd: Don't call mpz_set; inline its functionality.
+
+ * mpq_mul, mpq_div: Fix several serious typos.
+
+ * mpz_dmincl, mpz_div: Don't normalize the quotient if it's already
+ zero.
+
+ * mpq_neg.c: New file.
+
+ * dist-Makefile: Remove obsolete dependencies.
+
+ * mpz_sub: Fix typo.
+
+ Bugs found by Pierre-Joseph Gailly (pjg@sunbim.be):
+ * mpq_mul, mpq_div: Initialize tmp[12] variables even when the gcd
+ is just 1.
+ * mpz_gcd: Handle gcd(0,v) and gcd(u,0) in special cases.
+
+Sat Aug 3 23:45:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h: Clean up comments.
+ * longlong.h: #undef internal macros.
+
+Fri Aug 2 18:29:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_set_si, mpq_set_ui: Canonicalize 0/x to 0/1.
+ * mpq_set_si, mpq_set_ui: Cosmetic formatting changes.
+
+ * mpz_dmincl.c: Normalize the remainder before shifting it back.
+
+ * mpz_dm_ui.c (mpz_divmod_ui): Handle rem == dividend.
+
+ * mpn_div.c: Fix comment.
+
+ * mpz_add.c, mpz_sub.c: Use __MP_INT (not MP_INT) for intermediate
+ type, in order to work for both GNU and Berkeley functions.
+
+ * dist-Makefile: Create gcd.c from mpz_gcd.c, pow.c from mpz_powm,
+ madd.c from mpz_add.c, msub.c from mpz_sub.c.
+ respectively.
+ * pow.c, gcd.c, mpz_powmincl.c, madd.c, msub.c: Remove these.
+ * mpz_powm.c, mpz_gcd.c, mpz_add.c, mpz_sub.c: #ifdef for GNU and
+ Berkeley function name variants.
+ * dist-Makefile: Add created files to "clean" target.
+
+Tue Jul 16 15:19:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_get_den: No need for absolute value of the size, the
+ denominator is always positive.
+
+ * mpz_get_ui: If the operand is zero, return zero. Don't read the
+ limb array!
+
+ * mpz_dmincl.c: Don't ignore the return value from _mpn_rshift, it
+ is the size of the remainder.
+
+Mon Jul 15 11:08:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Several files: Remove unused variables and functions.
+
+ * gmp-impl.h: Declare _mpz_impl_sqrt.
+
+ * mpz_dm_ui (mpz_divmod_ui), sdiv: Shift back the remainder if
+ UDIV_NEEDS_NORMALIZATION. (Fix from Brian Beuning.)
+
+ * mpz_dm_ui.c, sdiv: Replace *digit with *limb.
+
+ * mpz_ior: Add missing else statement in -OP1 | -OP2 case.
+ * mpz_ior: Add missing else statement in OP1 | -OP2 case.
+ * mpz_ior: Swap also OP1 and OP2 pointers in -OP1 & OP2 case.
+ * mpz_ior: Duplicate _mpz_realloc code.
+
+ * mpz_and: Add missing else statement in -OP1 & -OP2 case.
+ * mpz_and: Rewrite OP1 & -OP2 case.
+ * mpz_and: Swap also OP1 and OP2 pointers in -OP1 & OP2 case.
+
+ * mpz_gcdext: Loop in d1.size (not b->size). (Fix from Brian
+ Beuning.)
+
+ * mpz_perfsqr: Fix argument order in _mpz_impl_sqrt call. (Fix from
+ Brian Beuning.)
+
+Fri Jul 12 17:10:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpq_set.c, mpq_set_ui.c, mpq_set_si.c, mpq_inv.c,
+ mpq_get_num.c, mpq_get_den.c, mpq_set_num.c, mpq_set_den.c:
+ New files.
+
+ * mpz_dmincl.c: Remove second re-allocation of rem->d. It
+ was never executed.
+
+ * dist-Makefile: Use `-r' instead of `-x' for test for ranlib (as
+ some unixes' test doesn't have the -r option).
+
+ * *.*: Cast allocated pointers to the appropriate type (makes old C
+ compilers happier).
+
+ * cre-conv-tab.c (main): Divide max_uli by 2 and multiply again
+ after conversion to double. (Kludge for broken C compilers.)
+
+ * dist-Makefile (stamp-stddefh): New target. Test if "stddef.h"
+ exists in the system and creates a minimal one if it does not
+ exist.
+ * cre-stddefh.c: New file.
+ * dist-Makefile: Make libgmp.a and libmp.a depend on stamp-stddefh.
+ * dist-Makefile (clean): Add some more.
+ * gmp.h, mp.h: Unconditionally include "stddef.h".
+
+Thu Jul 11 10:08:21 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * min: Do ungetc of last read character.
+ * min.c: include stdio.h.
+
+ * dist-Makefile: Go via tmp- files for cre* redirection.
+ * dist-Makefile: Add tmp* to "clean" target.
+
+ * dist-Makefile: Use LOCAL_CC for cre*, to simplyfy cross
+ compilation.
+
+ * gmp.h, mp.h: Don't define NULL here.
+ * gmp-impl.h: Define it here.
+
+Wed Jul 10 14:13:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_mod_2exp: Don't copy too much, overwriting most significant
+ limb.
+
+ * mpz_and, mpz_ior: Don't read op[12]_ptr from op[12] when
+ reallocating res, if op[12]_ptr got their value from alloca.
+
+ * mpz_and, mpz_ior: Clear up comments.
+
+ * cre-mparam.c: Output parameters for `short int' and `int'.
+
+ * mpz_and, mpz_ior: Negate negative op[12]_size in several places.
+
+Tue Jul 9 18:40:30 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp.h, mp.h: Test for _SIZE_T defined before typedef'ing size_t.
+ (Fix for Sun lossage.)
+
+ * gmp.h: Add declaration of mpq_clear.
+
+ * dist-Makefile: Chack if "ranlib" exists, before using it.
+ * dist-Makefile: Add mpz_sqrtrem.c and mpz_size.c.
+ * mpz_powm: Fix typo, "pow" instead of "mpz_powm".
+
+Fri Jul 5 19:08:09 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * move: Remove incorrect comment.
+
+ * mpz_free, mpq_free: Rename to *_clear.
+ * dist-Makefile: Likewise.
+ * mpq_add, mpq_sub, mpq_mul, mpq_div: Likewise.
+
+ * mpz_dmincl.c: Don't call "move", inline its functionality.
+
+Thu Jul 4 00:06:39 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Makefile: Include dist-Makefile. Fix dist target to include
+ dist-Makefile (with the name "Makefile" in the archive).
+
+ * dist-Makefile: New file made from Makefile. Add new mpz_...
+ functions.
+
+ * mpz_powincl.c New file for mpz_powm (Berkeley MP pow)
+ functionality. Avoids code duplication.
+ * pow.c, mpz_powm.c: Include mpz_powincl.c
+
+ * mpz_dmincl.c: New file containing general division code. Avoids
+ code duplication.
+ * mpz_dm.c (mpz_divmod), mpz_mod.c (mpz_mod), mdiv.c (mdiv): Include
+ mpz_dmincl.c.
+
+ * _mpz_get_str: Don't call memmove, unless HAS_MEMMOVE is defined.
+ Instead, write the overlapping memory copying inline.
+
+ * mpz_dm_ui.c: New name for mpz_divmod_ui.c (SysV file name limit).
+
+ * longlong.h: Don't use #elif.
+ * mpz_do_sqrt.c: Likewise.
+
+ * longlong.h: Use __asm__ instead of asm.
+ * longlong.h (sparc udiv_qrnnd): Make it to one string over several
+ lines.
+
+ * longlong.h: Preend __ll_ to B, highpart, and lowpart.
+
+ * longlong.h: Move array t in count_leading_zeros to the new file
+ mp_clz_tab.c. Rename the array __clz_tab.
+ * All files: #ifdef for traditional C compatibility.
+
+Wed Jul 3 11:42:14 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_and: Initialize res_ptr always (used to be initialized only
+ when reallocating).
+
+ * longlong.h (umul_ppmm [C variant]): Make __ul...__vh
+ `unsigned int', and cast the multiplications. This way
+ compilers more easily can choose cheaper multiplication
+ instructions.
+
+ * mpz_mod_2exp: Handle input argument < modulo argument.
+ * mpz_many: Make sure mp_size is the type for sizes, not int.
+
+ * mpz_init, mpz_init_set*, mpq_init, mpq_add, mpq_sub, mpq_mul,
+ mpq_div: Change mpz_init* interface. Structure pointer as first
+ arg to initialization function, no longer *return* struct.
+
+Sun Jun 30 19:21:44 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Rename mpz_impl_sqrt.c to mpz_do_sqrt.c to satisfy SysV 14
+ character file name length limit.
+
+ * Most files: Rename MINT to MP_INT. Rename MRAT to MP_RAT.
+ * mpz_sizeinb.c: New file with function mpz_sizeinbase.
+ * mp_bases.c: New file, with array __mp_bases.
+ * _mpz_get_str, _mpz_set_str: Remove struct bases, use extern
+ __mp_bases instead.
+ * mout, mpz_out_str: Use array __mp_bases instead of function
+ _mpz_get_cvtlen.
+ * mpz_get_cvtlen.c: Remove.
+ * Makefile: Update.
+
+Sat Jun 29 21:57:28 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * longlong.h (__sparc8__ umul_ppmm): Insert 3 nop:s for wr delay.
+ * longlong.h (___IBMR2__): Define umul_ppmm, add_ssaaaa, sub_ddmmss.
+ * longlong.h (__sparc__): Don't call .umul; expand asm instead.
+ Don't define __umulsidi3 (i.e. use default definition).
+
+Mon Jun 24 17:37:23 1991 Torbjorn Granlund (tege@amon.sics.se)
+
+ * _mpz_get_str.c (num_to_ascii_lower_case, num_to_ascii_upper_case):
+ Swap 't' and 's'.
+
+Sat Jun 22 13:54:01 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_gcdext.c: New file.
+
+ * mpn_mul: Handle carry and unexpected operand sizes in last
+ additions/subtractions. (Bug trigged when v1_size == 1.)
+
+ * mp*_alloc*: Rename functions to mp*_init* (files to mp*_iset*.c).
+ * mpq_*: Call mpz_init*.
+
+ * mpz_pow_ui, rpow: Use _mpn_mul instead of mult. Restructure.
+
+Wed May 29 20:32:33 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_get_cvtlen: multiply by size.
+
+Sun May 26 15:01:15 1991 Torbjorn Granlund (tege@bella.nada.kth.se)
+
+ Alpha-release 0.95.
+
+ Fixes from Doug Lea (dl@g.oswego.edu):
+ * mpz_mul_ui: Loop to MULT_SIZE (not PROD_SIZE). Adjust PROD_SIZE
+ correctly.
+ * mpz_div: Prepend _ to mpz_realloc.
+ * mpz_set_xs, mpz_set_ds: Fix typos in function name.
+
+Sat May 25 22:51:16 1991 Torbjorn Granlund (tege@bella.nada.kth.se)
+
+ * mpz_divmod_ui: New function.
+
+ * sdiv: Make the sign of the remainder correct.
+
+Thu May 23 15:28:24 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Alpha-release 0.94.
+
+ * mpz_mul_ui: Include longlong.h.
+
+ * mpz_perfsqr.c (mpz_perfect_square_p): Call _mpz_impl_sqrt instead
+ of msqrt.
+
+ * mpz_impl_sqrt: Don't call "move", inline its functionality.
+
+ * mdiv: Use MPN_COPY instead of memcpy.
+ * rpow, mpz_mul, mpz_mod_2exp: Likewise.
+ * pow.c: Likewise, and fix bug in the size arg.
+
+ * xtom: Don't use mpz_alloc, inline needed code instead. Call
+ _mpz_set_str instead of mpz_set_str.
+
+ * Makefile: Make two libraries, libmp.a and libgmp.a.
+
+Thu May 22 20:25:29 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Add manual to distribution.
+ * Fold in many missing routines descibed in the manual.
+ * Update Makefile.
+
+Wed May 22 13:48:46 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_set_str: Make it handle 0x prefix OK.
+
+Sat May 18 18:31:02 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * memory.c (_mp_default_reallocate): Swap OLD_SIZE and NEW_SIZE
+ arguments.
+ * mpz_realloc (_mpz_realloc): Swap in call to _mp_reallocate_func.
+ * min: Likewise.
+
+Thu May 16 20:43:05 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * memory.c: Make the default allocations functions global.
+ * mp_set_fns (mp_set_memory_functions): Make a NULL pointer mean the
+ default memory function.
+
+Wed May 8 20:02:42 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_div: Handle DEN the same as QUOT correctly by copying DEN->D
+ even if no normalization is needed.
+ * mpz_div: Rework reallocation scheme, to avoid excess copying.
+
+ * mpz_sub_ui.c, mpz_add_ui.c: New files.
+
+ * mpz_cmp.c, mpz_cmp_ui.c: New files.
+
+ * mpz_mul_2exp: Handle zero input MINT correctly.
+
+ * mpn_rshiftci: Don't handle shift counts > BITS_PER_MP_DIGIT.
+
+ * mpz_out_raw.c, mpz_inp_raw.c: New files for raw I/O.
+
+Tue May 7 15:44:58 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_rshift: Don't handle shift counts > BITS_PER_MP_DIGIT.
+ * mpz_div_2exp: Don't call _mpn_rshift with cnt > BITS_PER_MP_DIGIT.
+ * gcd, mpz_gcd: Likewise.
+
+ * gcd, mpz_gcd: Handle common 2 factors correctly.
+
+Mon May 6 20:22:59 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * gmp-impl.h (MPN_COPY): Inline a loop instead of calling memcpy.
+
+ * gmp-impl.h, mpz_get_str, rpow: Swap DST and SRC in TMPCOPY* macros.
+
+Sun May 5 15:16:23 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpz_div: Remove test for QUOT == 0.
+
+Sun Apr 28 20:21:04 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * pow: Don't make MOD normalization in place, as it's a bad idea to
+ write on an input parameter.
+ * pow: Reduce BASE if it's > MOD.
+ * pow, mult, mpz_mul: Simplify realloc code.
+
+Sat Apr 27 21:03:11 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * Install multplication using Karatsuba's algorithm as default.
+
+Fri Apr 26 01:03:57 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * msqrt: Store in ROOT even for U==0, to make msqrt(0) defined.
+
+ * mpz_div_2exp.c, mpz_mul_2exp.c: New files for shifting right and
+ left, respectively.
+ * gmp.h: Add definitions for mpz_div_2exp and mpz_mul_2exp.
+
+ * mlshift.c, mrshift.c: Remove.
+
+Wed Apr 24 21:39:22 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * mpn_mul: Check only for m2_size == 0 in function header.
+
+Mon Apr 22 01:31:57 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * karatsuba.c: New file for Karatsuba's multplication algorithm.
+
+ * mpz_random, mpz_init, mpz_mod_2exp: New files and functions.
+
+ * mpn_cmp: Fix header comment.
+
+Sun Apr 21 00:10:44 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * pow: Switch off initial base reduction.
+
+Sat Apr 20 22:06:05 1991 Torbjorn Granlund (tege@echnaton.sics.se)
+
+ * mpz_get_str: Don't generate initial zeros for initial word.
+ Used to write outside of allocated storage.
+
+Mon Apr 15 15:48:08 1991 Torbjorn Granlund (tege@zevs.sics.se)
+
+ * _mpz_realloc: Make it accept size in number of mp_digits.
+ * Most functions: Use new _mpz_realloc definition.
+
+ * mpz_set_str: Remove calls _mp_free_func.
+
+ * Most functions: Rename mpn_* to _mpn_*. Rename mpz_realloc to
+ _mpz_realloc.
+ * mpn_lshift: Redefine _mpn_lshift to only handle small shifts.
+ * mdiv, mpz_div, ...: Changes for new definition of _mpn_lshift.
+ * msqrt, mp*_*shift*: Define cnt as unsigned (for speed).
+
+Sat Apr 6 14:05:16 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mpn_mul: Multiply by the first digit in M2 in a special
+ loop instead of zeroing the product area.
+
+ * mpz_abs.c: New file.
+
+ * sdiv: Implement as mpz_div_si for speed.
+
+ * mpn_add: Make it work for second source operand == 0.
+
+ * msub: Negate the correct operand, i.e. V before swapping, not
+ the smaller of U and V!
+ * madd, msub: Update abs_* when swapping operands, and not after
+ (optimization).
+
+Fri Apr 5 00:19:36 1991 Torbjorn Granlund (tege@black.nada.kth.se)
+
+ * mpn_sub: Make it work for subtrahend == 0.
+
+ * madd, msub: Rewrite to minimize mpn_cmp calls. Ensure
+ mpn_cmp is called with positive sizes (used to be called
+ incorrectly with negative sizes sometimes).
+
+ * msqrt: Make it divide by zero if fed with a negative number.
+ * Remove if statement at end of precision calculation that was
+ never true.
+
+ * itom, mp.h: The argument is of type short, not int.
+
+ * mpz_realloc, gmp.h: Make mpz_realloc return the new digit pointer.
+
+ * mpz_get_str.c, mpz_set_str.c, mpz_new_str.c: Don't include mp.h.
+
+ * Add COPYING to distribution.
+
+ * mpz_div_ui.c, mpz_div_si.c, mpz_new_ui.c, mpz_new_si.c: New files.
+
+Fri Mar 15 00:26:29 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * Add Copyleft headers to all files.
+
+ * mpn_mul.c, mpn_div.c: Add header comments.
+ * mult.c, mdiv.c: Update header comments.
+
+ * mpq_add.c, mpq_sub.c, mpq_div.c, mpq_new.c, mpq_new_ui.c,
+ mpq_free.c: New files for rational arithmetics.
+
+ * mpn_lshift.c: Avoid writing the most significant word if it is 0.
+
+ * mdiv.c: Call mpn_lshift for the normalization.
+ * mdiv.c: Remove #ifdefs.
+
+ * Makefile: Add ChangeLog to DISTFILES.
+
+ * mpn_div.c: Make the add_back code work (by removing abort()).
+ * mpn_div.c: Make it return if the quotient is size as compared
+ with the difference NSIZE - DSIZE. If the stored quotient is
+ larger than that, return 1, otherwise 0.
+ * gmp.h: Fix mpn_div declaration.
+ * mdiv.c: Adopt call to mpn_div.
+ * mpz_div.c: New file (developed from mdiv.c).
+
+ * README: Update routine names.
+
+Thu Mar 14 18:45:28 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mpq_mul.c: New file for rational multplication.
+
+ * gmp.h: Add definitions for rational arithmetics.
+
+ * mpn_div: Kludge the case where the high numerator digit > the
+ high denominator digit. (This code is going to be optimized later.)
+
+ * New files: gmp.h for GNU specific functions, gmp-common.h for
+ definitions common for mp.h and gmp.h.
+
+ * Ensure mp.h just defines what BSD mp.h defines.
+
+ * pow.c: Fix typo for bp allocation.
+
+ * Rename natural number functions to mpn_*, integer functions to
+ mpz_*.
+
+Tue Mar 5 18:47:04 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * mdiv.c (_mp_divide, case 2): Change test for estimate of Q from
+ "n0 >= r" to "n0 > r".
+
+ * msqrt: Tune the increasing precision scheme, to do fewer steps.
+
+Tue Mar 3 18:50:10 1991 Torbjorn Granlund (tege@musta.nada.kth.se)
+
+ * msqrt: Use the low level routines. Use low precision in the
+ beginning, and increase the precision as the result converges.
+ (This optimization gave a 6-fold speedup.)
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+fill-column: 75
+version-control: never
+End:
diff --git a/gnu/lib/libgmp/INSTALL b/gnu/lib/libgmp/INSTALL
new file mode 100644
index 0000000..38bfaa8
--- /dev/null
+++ b/gnu/lib/libgmp/INSTALL
@@ -0,0 +1,154 @@
+INSTALLING GMP
+==============
+
+These instructions are only for the impatient. Others should read the install
+instructions in the manual, gmp.info. Use "info -f gmp.info", or, if you
+don't have info, use type "C-h i g (gmp.info)Top" in emacs.
+
+Here are short instructions how to install MP, and some examples that help you
+get started using MP.
+
+First, you need to compile, and optionally install, MP. Since you're
+impatient, try this:
+
+ ./configure; make
+
+If that fails, or you care about the performance of MP, you need to read the
+full instructions in the chapter "Installing MP", in the manual.
+
+Next, you need to try some small test programs, for example the ones below.
+
+In MP programs, all variables need to be initialized before they are assigned,
+and cleared out before program flow leaves the scope in which it was declared.
+Here is an example of a program that reads two numbers from the command line,
+multiplies them, and prints the result to stdout.
+
+ #include <stdio.h>
+ #include <gmp.h> /* All MP programs need to include gmp.h */
+
+ main (int argc, char **argv)
+ {
+ mpz_t a, b, p;
+
+ /* Initialize variables */
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (p);
+
+ /* Assign a and b from base 10 strings in argv */
+ mpz_set_str (a, argv[1], 10);
+ mpz_set_str (b, argv[2], 10);
+
+ /* Multiply a and b and put the result in p */
+ mpz_mul (p, a, b);
+
+ /* Print p in base 10 */
+ mpz_out_str (stdout, 10, p);
+ fputc ('\n', stdout);
+
+ /* Clear out variables */
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (p);
+ exit (0);
+ }
+
+
+In practice, that example would be written like this instead:
+
+ #include <stdio.h>
+ #include <gmp.h>
+
+ main (int argc, char **argv)
+ {
+ mpz_t a, b, p;
+
+ /* Initialize and assign a and b from base 10 strings in argv */
+ mpz_init_set_str (a, argv[1], 10);
+ mpz_init_set_str (b, argv[2], 10);
+ /* Initialize p */
+ mpz_init (p);
+
+ /* Multiply a and b and put the result in p */
+ mpz_mul (p, a, b);
+
+ /* Print p in base 10 */
+ mpz_out_str (stdout, 10, p);
+ fputc ('\n', stdout);
+
+ /* Since we're about to exit, no need to clear out variables */
+ exit (0);
+ }
+
+Finally, you have to compile your test program, and link it with the MP
+library. Assuming your working directory is still the gmp source directory,
+type:
+
+ gcc -g -I. example.c libgmp.a
+
+
+Now try to run the example:
+
+ a.out 98365871231256752134 319378318340103345227
+ 31415926535897932384618573336104570964418
+
+The functions used here all operate on the domain of signed integers.
+Functions operating on that domain have names starting with "mpz_". There are
+many more such functions than used in these examples. See the chapter
+"Integer Functions" in the manual, for a complete list.
+
+There are two other main classes of functions in MP. They operate on rational
+numbers and floating-point numbers, respectively. The chapters "Rational
+Number Functions", and "Floating-point Functions" documents these classes.
+
+To run a set of tests, do "make check". This will take a while.
+
+To create the printable documentation from the texinfo source, type "make
+dvi". This requires the "tex" command to be available in your search path.
+
+To install the library, do "make install".
+
+If you decide to use MP, It is a good idea you read at least the chapter "MP
+Basics" in the manual.
+
+
+Known Build Problems
+--------------------
+
+Note that GCC 2.7.2 (as well as 2.6.3) for the RS/6000 and PowerPC can not
+be used to compile GMP, due to a bug in GCC. If you want to use GCC, you
+need to apply the patch at the end of this file, or use a later version of
+the compiler.
+
+If you are on a Sequent Symmetry, use GAS instead of the system's assembler
+due to the latter's serious bugs.
+
+The system compiler on NeXT is a massacred and old gcc, even if the
+compiler calls itself cc. This compiler cannot be used to build GMP. You
+need to get a real gcc, and install that before you compile GMP. (NeXT
+might have fixed this in newer releases of their system.)
+
+Please report other problems to bug-gmp@prep.ai.mit.edu.
+
+
+Patch to apply to GCC 2.6.3 and 2.7.2:
+
+*** config/rs6000/rs6000.md Sun Feb 11 08:22:11 1996
+--- config/rs6000/rs6000.md.new Sun Feb 18 03:33:37 1996
+***************
+*** 920,926 ****
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+! "nor. %0,%2,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
+--- 920,926 ----
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+! "nor. %0,%1,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
diff --git a/gnu/lib/libgmp/Makefile b/gnu/lib/libgmp/Makefile
new file mode 100644
index 0000000..d9aaead
--- /dev/null
+++ b/gnu/lib/libgmp/Makefile
@@ -0,0 +1,62 @@
+# Makefile for libgmp
+# $Id: Makefile,v 1.4 1996/05/07 23:14:38 wosch Exp $
+
+LIB= gmp
+SRCS= $(GMP_SRCS)
+CLEANFILES+= cre-mparam cre-conv-tab gmp-mparam.h mp_bases.c
+
+GMP_SRCS= mp_bases.c $(MPZ_SRCS) $(MPQ_SRCS) $(MPN_SRCS) $(IMPL_SRCS)
+
+CFLAGS+= -I${.CURDIR} -I${.OBJDIR} -Wall -Wstrict-prototypes -DLOCALE
+
+MPN_SRCS= mpn_add.c mpn_sub.c mpn_cmp.c mpn_mul.c mpn_div.c mpn_dm_1.c \
+ mpn_mod_1.c mpn_lshift.c mpn_rshift.c mpn_rshiftci.c mpn_sqrt.c
+
+IMPL_SRCS= memory.c mp_set_fns.c _mpz_set_str.c _mpz_get_str.c \
+ mpz_realloc.c mp_clz_tab.c
+
+MPZ_SRCS= mpz_init.c mpz_set.c mpz_set_ui.c mpz_set_si.c mpz_set_str.c \
+ mpz_iset.c mpz_iset_ui.c mpz_iset_si.c mpz_iset_str.c \
+ mpz_clear.c mpz_get_ui.c mpz_get_si.c mpz_get_str.c \
+ mpz_size.c mpz_sizeinb.c mpz_add.c mpz_add_ui.c mpz_sub.c \
+ mpz_sub_ui.c mpz_mul.c mpz_mul_ui.c mpz_div.c mpz_div_ui.c \
+ mpz_mod.c mpz_mod_ui.c mpz_dm.c mpz_dm_ui.c mpz_mdiv.c \
+ mpz_mmod.c mpz_mdm.c mpz_mdiv_ui.c mpz_mmod_ui.c mpz_mdm_ui.c \
+ mpz_gcd.c mpz_gcdext.c mpz_sqrt.c mpz_sqrtrem.c mpz_powm.c \
+ mpz_powm_ui.c mpz_cmp.c mpz_cmp_ui.c mpz_cmp_si.c \
+ mpz_mul_2exp.c mpz_div_2exp.c mpz_mod_2exp.c mpz_abs.c \
+ mpz_neg.c mpz_com.c mpz_and.c mpz_ior.c mpz_inp_raw.c \
+ mpz_inp_str.c mpz_out_raw.c mpz_out_str.c mpz_perfsqr.c \
+ mpz_random.c mpz_random2.c mpz_pow_ui.c mpz_clrbit.c \
+ mpz_fac_ui.c mpz_pprime_p.c
+
+MPQ_SRCS= mpq_init.c mpq_set.c mpq_set_ui.c mpq_set_si.c \
+ mpq_set_num.c mpq_set_den.c mpq_get_num.c mpq_get_den.c \
+ mpq_add.c mpq_sub.c mpq_mul.c mpq_div.c mpq_clear.c \
+ mpq_cmp.c mpq_inv.c mpq_neg.c
+
+SUBDIR+= doc
+
+beforedepend: gmp-mparam.h mp_bases.c
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/gmp.h \
+ ${DESTDIR}/usr/include
+
+cre-mparam: cre-mparam.c
+ $(CC) $(CFLAGS) ${.CURDIR}/cre-mparam.c -o ${.TARGET}
+
+cre-conv-tab: cre-conv-tab.c gmp-mparam.h
+ $(CC) $(CFLAGS) -lm ${.CURDIR}/cre-conv-tab.c -o ${.TARGET}
+
+cre-conv-tab: gmp-mparam.h
+
+gmp-mparam.h: cre-mparam
+ ./cre-mparam > tmp-${.TARGET}
+ mv -f tmp-${.TARGET} ${.TARGET}
+
+mp_bases.c: cre-conv-tab
+ ./cre-conv-tab > tmp-${.TARGET}
+ mv -f tmp-${.TARGET} ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libgmp/Makefile.GNU b/gnu/lib/libgmp/Makefile.GNU
new file mode 100644
index 0000000..f639de3
--- /dev/null
+++ b/gnu/lib/libgmp/Makefile.GNU
@@ -0,0 +1,289 @@
+# Makefile for GNU MP (a.k.a. biGNUm)
+# Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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.
+
+# You should have received a copy of the GNU General Public License
+# along with the GNU MP Library; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CC = gcc
+
+# If you cross compile on a machine with the same sizes of the integral
+# types ("int", "long int", "short int", and "char") define this as the
+# local compiler. Otherwise, you need look for the uses of LOCAL_CC below,
+# and handle those cases manually.
+LOCAL_CC = $(CC)
+OPT = -O -g
+CFLAGS = -I. $(OPT)
+AR = ar
+RANLIB=`if [ -r /bin/ranlib -o -r /usr/bin/ranlib ]; \
+ then echo ranlib; else echo true; fi`
+SHELL = /bin/sh
+
+SRCS = $(MPZ_SRCS) $(MPQ_SRCS) $(BSDMP_SRCS) $(MPN_SRCS) $(IMPL_SRCS)
+OBJS = $(MPZ_OBJS) $(MPQ_OBJS) $(BSDMP_OBJS) $(MPN_OBJS) $(IMPL_OBJS)
+
+MP_OBJS = $(BSDMP_OBJS) $(MPN_OBJS) $(IMPL_OBJS) mp_bases.o mpz_sizeinb.o
+GMP_OBJS = $(MPZ_OBJS) $(MPQ_OBJS) $(MPN_OBJS) $(IMPL_OBJS) mp_bases.o
+
+IMPL_SRCS = memory.c mp_set_fns.c _mpz_set_str.c _mpz_get_str.c \
+ mpz_realloc.c mp_clz_tab.c alloca.c
+IMPL_OBJS = memory.o mp_set_fns.o _mpz_set_str.o _mpz_get_str.o \
+ mpz_realloc.o mp_clz_tab.o alloca.o
+
+MPZ_SRCS = mpz_init.c mpz_set.c mpz_set_ui.c mpz_set_si.c mpz_set_str.c \
+ mpz_iset.c mpz_iset_ui.c mpz_iset_si.c mpz_iset_str.c mpz_clear.c \
+ mpz_get_ui.c mpz_get_si.c mpz_get_str.c mpz_size.c mpz_sizeinb.c \
+ mpz_add.c mpz_add_ui.c mpz_sub.c mpz_sub_ui.c mpz_mul.c mpz_mul_ui.c \
+ mpz_div.c mpz_div_ui.c mpz_mod.c mpz_mod_ui.c mpz_dm.c mpz_dm_ui.c \
+ mpz_mdiv.c mpz_mmod.c mpz_mdm.c mpz_mdiv_ui.c mpz_mmod_ui.c mpz_mdm_ui.c \
+ mpz_gcd.c mpz_gcdext.c mpz_sqrt.c mpz_sqrtrem.c mpz_powm.c mpz_powm_ui.c \
+ mpz_cmp.c mpz_cmp_ui.c mpz_cmp_si.c mpz_mul_2exp.c mpz_div_2exp.c \
+ mpz_mod_2exp.c mpz_abs.c mpz_neg.c mpz_com.c mpz_and.c mpz_ior.c \
+ mpz_inp_raw.c mpz_inp_str.c mpz_out_raw.c mpz_out_str.c \
+ mpz_perfsqr.c mpz_random.c mpz_random2.c mpz_pow_ui.c \
+ mpz_clrbit.c mpz_fac_ui.c mpz_pprime_p.c
+MPZ_OBJS = mpz_init.o mpz_set.o mpz_set_ui.o mpz_set_si.o mpz_set_str.o \
+ mpz_iset.o mpz_iset_ui.o mpz_iset_si.o mpz_iset_str.o mpz_clear.o \
+ mpz_get_ui.o mpz_get_si.o mpz_get_str.o mpz_size.o mpz_sizeinb.o \
+ mpz_add.o mpz_add_ui.o mpz_sub.o mpz_sub_ui.o mpz_mul.o mpz_mul_ui.o \
+ mpz_div.o mpz_div_ui.o mpz_mod.o mpz_mod_ui.o mpz_dm.o mpz_dm_ui.o \
+ mpz_mdiv.o mpz_mmod.o mpz_mdm.o mpz_mdiv_ui.o mpz_mmod_ui.o mpz_mdm_ui.o \
+ mpz_gcd.o mpz_gcdext.o mpz_sqrt.o mpz_sqrtrem.o mpz_powm.o mpz_powm_ui.o \
+ mpz_cmp.o mpz_cmp_ui.o mpz_cmp_si.o mpz_mul_2exp.o mpz_div_2exp.o \
+ mpz_mod_2exp.o mpz_abs.o mpz_neg.o mpz_com.o mpz_and.o mpz_ior.o \
+ mpz_inp_raw.o mpz_inp_str.o mpz_out_raw.o mpz_out_str.o \
+ mpz_perfsqr.o mpz_random.o mpz_random2.o mpz_pow_ui.o \
+ mpz_clrbit.o mpz_fac_ui.o mpz_pprime_p.o
+
+MPQ_SRCS = mpq_init.c mpq_set.c mpq_set_ui.c mpq_set_si.c \
+ mpq_set_num.c mpq_set_den.c mpq_get_num.c mpq_get_den.c \
+ mpq_add.c mpq_sub.c mpq_mul.c mpq_div.c \
+ mpq_clear.c mpq_cmp.c mpq_inv.c mpq_neg.c
+MPQ_OBJS = mpq_init.o mpq_set.o mpq_set_ui.o mpq_set_si.o \
+ mpq_set_num.o mpq_set_den.o mpq_get_num.o mpq_get_den.o \
+ mpq_add.o mpq_sub.o mpq_mul.o mpq_div.o \
+ mpq_clear.o mpq_cmp.o mpq_inv.o mpq_neg.o
+
+MPN_SRCS = mpn_add.c mpn_sub.c mpn_cmp.c mpn_mul.c mpn_div.c mpn_dm_1.c \
+ mpn_mod_1.c mpn_lshift.c mpn_rshift.c mpn_rshiftci.c mpn_sqrt.c
+MPN_OBJS = mpn_add.o mpn_sub.o mpn_cmp.o mpn_mul.o mpn_div.o mpn_dm_1.o \
+ mpn_mod_1.o mpn_lshift.o mpn_rshift.o mpn_rshiftci.o mpn_sqrt.o
+
+# There are fewer members in the BSDMP_SRCS list that in the BSDMP_OBJS
+# list because some of the .c files are created by this Makefile.
+BSDMP_SRCS = itom.c mdiv.c move.c mtox.c xtom.c sdiv.c mout.c min.c mfree.c
+BSDMP_OBJS = gcd.o itom.o madd.o mcmp.o mdiv.o move.o msub.o mtox.o mult.o \
+ pow.o rpow.o xtom.o msqrt.o sdiv.o mout.o min.o mfree.o
+
+all: libgmp.a libmp.a
+
+check: libgmp.a
+ cd tests; $(MAKE) CC="$(CC)" SHELL="$(SHELL)" OPT="$(OPT)"
+
+libgmp.a: stamp-stddefh $(GMP_OBJS)
+ rm -f $@
+ $(AR) cr $@ $(GMP_OBJS)
+ $(RANLIB) $@
+
+# libmp.a depend on libgmp.a, to get around Unix(tm) ar/ranlib concurrency bug.
+libmp.a: stamp-stddefh $(MP_OBJS) libgmp.a
+ rm -f $@
+ $(AR) cr $@ $(MP_OBJS)
+ $(RANLIB) $@
+
+stamp-stddefh:
+ rm -f stddef.h
+ rm -f test-stddefh.c
+ ( echo '#include <stddef.h>' ;\
+ echo 'main(){size_t foo=sizeof(size_t);exit(0);}' ;\
+ ) > test-stddefh.c
+ @if $(LOCAL_CC) $(CFLAGS) test-stddefh.c -c 2> /dev/null ;\
+ then true ;\
+ else \
+ echo 'This machine has no "stddef.h". Creating a minimal in ./';\
+ $(LOCAL_CC) $(CFLAGS) cre-stddefh.c -o cre-stddefh ;\
+ ./cre-stddefh > stddef.h ;\
+ fi
+ rm -f test-stddefh.o
+ touch stamp-stddefh
+
+mp_bases.c: cre-conv-tab
+ ./cre-conv-tab > tmp-$@
+ mv tmp-$@ $@
+cre-conv-tab: cre-conv-tab.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+ $(LOCAL_CC) $(CFLAGS) `if [ x$(firstword $^) = x ]; \
+ then echo cre-conv-tab.c; \
+ else echo $(firstword $^); fi` -o $@ -lm
+
+gmp-mparam.h: cre-mparam
+ ./cre-mparam > tmp-$@
+ mv tmp-$@ $@
+cre-mparam: cre-mparam.c stamp-stddefh gmp.h
+ $(LOCAL_CC) $(CFLAGS) cre-mparam.c -o $@
+
+gcd.c : mpz_gcd.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h longlong.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_gcd.c \
+ | grep -v '^#' > $@
+pow.c : mpz_powm.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h longlong.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_powm.c\
+ | grep -v '^#' > $@
+rpow.c: mpz_pow_ui.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h longlong.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_pow_ui.c\
+ | grep -v '^#' > $@
+madd.c : mpz_add.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_add.c\
+ | grep -v '^#' > $@
+msub.c : mpz_sub.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_sub.c\
+ | grep -v '^#' > $@
+mult.c : mpz_mul.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_mul.c\
+ | grep -v '^#' > $@
+mcmp.c : mpz_cmp.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_cmp.c\
+ | grep -v '^#' > $@
+msqrt.c : mpz_sqrtrem.c stamp-stddefh mp.h gmp.h gmp-impl.h gmp-mparam.h
+ $(CC) $(CFLAGS) -E -DBERKELEY_MP mpz_sqrtrem.c\
+ | grep -v '^#' > $@
+
+doc: gmp.dvi gmp.info
+LN = ln -s
+gmp.dvi: gmp.texi
+ rm -f tmp.texi
+ $(LN) gmp.texi tmp.texi
+ tex tmp.texi < /dev/null
+ texindex tmp.cp tmp.fn
+ tex tmp.texi < /dev/null 2> /dev/null
+ mv tmp.dvi gmp.dvi
+gmp.info: gmp.texi
+ makeinfo gmp.texi
+
+clean:
+ rm -f *.o libgmp.a libmp.a cre-conv-tab cre-mparam cre-stddefh \
+ gmp.dvi gmp.info mp_bases.c gmp-mparam.h stamp-stddefh test-stddefh.c \
+ stddef.h gcd.c pow.c rpow.c madd.c msub.c mult.c mcmp.c msqrt.c \
+ tmp.* tmp-* gmp.ps core
+ -cd tests; $(MAKE) clean
+realclean: clean
+
+# Automatically generated dependencies
+
+_mpz_get_str.o : _mpz_get_str.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+_mpz_set_str.o : _mpz_set_str.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+cre-conv-tab.o : cre-conv-tab.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+cre-mparam.o : cre-mparam.c gmp.h
+cre-stddefh.o : cre-stddefh.c
+itom.o : itom.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+mdiv.o : mdiv.c mp.h gmp.h gmp-impl.h gmp-mparam.h longlong.h mpz_dmincl.c
+memory.o : memory.c gmp.h gmp-impl.h gmp-mparam.h
+mfree.o : mfree.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+min.o : min.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+mout.o : mout.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+move.o : move.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+mp_bases.o : mp_bases.c gmp.h gmp-impl.h gmp-mparam.h
+mp_clz_tab.o : mp_clz_tab.c gmp.h gmp-impl.h gmp-mparam.h
+mp_set_fns.o : mp_set_fns.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_add.o : mpn_add.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_cmp.o : mpn_cmp.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_div.o : mpn_div.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpn_dm_1.o : mpn_dm_1.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpn_lshift.o : mpn_lshift.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_mod_1.o : mpn_mod_1.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpn_mul.o : mpn_mul.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpn_rshift.o : mpn_rshift.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_rshiftci.o : mpn_rshiftci.c gmp.h gmp-impl.h gmp-mparam.h
+mpn_sqrt.o : mpn_sqrt.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpn_sub.o : mpn_sub.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_add.o : mpq_add.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_clear.o : mpq_clear.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_cmp.o : mpq_cmp.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_div.o : mpq_div.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_get_den.o : mpq_get_den.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_get_num.o : mpq_get_num.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_init.o : mpq_init.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_inv.o : mpq_inv.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_mul.o : mpq_mul.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_neg.o : mpq_neg.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_set.o : mpq_set.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_set_den.o : mpq_set_den.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_set_num.o : mpq_set_num.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_set_si.o : mpq_set_si.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_set_ui.o : mpq_set_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpq_sub.o : mpq_sub.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_abs.o : mpz_abs.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_add.o : mpz_add.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_add_ui.o : mpz_add_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_and.o : mpz_and.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_clear.o : mpz_clear.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_clrbit.o : mpz_clrbit.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_cmp.o : mpz_cmp.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_cmp_si.o : mpz_cmp_si.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_cmp_ui.o : mpz_cmp_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_com.o : mpz_com.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_div.o : mpz_div.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_div_2exp.o : mpz_div_2exp.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_div_ui.o : mpz_div_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_dm.o : mpz_dm.c gmp.h gmp-impl.h gmp-mparam.h longlong.h mpz_dmincl.c
+mpz_dm_ui.o : mpz_dm_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_fac_ui.o : mpz_fac_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_gcd.o : mpz_gcd.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_gcdext.o : mpz_gcdext.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_get_si.o : mpz_get_si.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_get_str.o : mpz_get_str.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_get_ui.o : mpz_get_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_init.o : mpz_init.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_inp_raw.o : mpz_inp_raw.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_inp_str.o : mpz_inp_str.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_ior.o : mpz_ior.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_iset.o : mpz_iset.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_iset_si.o : mpz_iset_si.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_iset_str.o : mpz_iset_str.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_iset_ui.o : mpz_iset_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mdiv.o : mpz_mdiv.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mdiv_ui.o : mpz_mdiv_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mdm.o : mpz_mdm.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mdm_ui.o : mpz_mdm_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mmod.o : mpz_mmod.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mmod_ui.o : mpz_mmod_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mod.o : mpz_mod.c gmp.h gmp-impl.h gmp-mparam.h longlong.h mpz_dmincl.c
+mpz_mod_2exp.o : mpz_mod_2exp.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mod_ui.o : mpz_mod_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_mul.o : mpz_mul.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mul_2exp.o : mpz_mul_2exp.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_mul_ui.o : mpz_mul_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_neg.o : mpz_neg.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_out_raw.o : mpz_out_raw.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_out_str.o : mpz_out_str.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_perfsqr.o : mpz_perfsqr.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_pow_ui.o : mpz_pow_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_powm.o : mpz_powm.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_powm_ui.o : mpz_powm_ui.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_pprime_p.o : mpz_pprime_p.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_random.o : mpz_random.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_random2.o : mpz_random2.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_realloc.o : mpz_realloc.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_set.o : mpz_set.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_set_si.o : mpz_set_si.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_set_str.o : mpz_set_str.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_set_ui.o : mpz_set_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_size.o : mpz_size.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_sizeinb.o : mpz_sizeinb.c gmp.h gmp-impl.h gmp-mparam.h longlong.h
+mpz_sqrt.o : mpz_sqrt.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_sqrtrem.o : mpz_sqrtrem.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_sub.o : mpz_sub.c gmp.h gmp-impl.h gmp-mparam.h
+mpz_sub_ui.o : mpz_sub_ui.c gmp.h gmp-impl.h gmp-mparam.h
+mtox.o : mtox.c mp.h gmp.h gmp-impl.h gmp-mparam.h
+sdiv.o : sdiv.c mp.h gmp.h gmp-impl.h gmp-mparam.h longlong.h
+xtom.o : xtom.c mp.h gmp.h gmp-impl.h gmp-mparam.h
diff --git a/gnu/lib/libgmp/Makefile.in b/gnu/lib/libgmp/Makefile.in
new file mode 100644
index 0000000..6d7ff61
--- /dev/null
+++ b/gnu/lib/libgmp/Makefile.in
@@ -0,0 +1,210 @@
+# Top Makefile for GNU MP
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+prefix = /usr/local
+
+exec_prefix = $(prefix)
+libdir = $(exec_prefix)/lib
+infodir = $(prefix)/info
+includedir = $(prefix)/include
+
+CC = gcc
+LOCAL_CC = $(CC)
+CFLAGS = -g -O
+XCFLAGS =
+AR = ar
+AR_FLAGS = rc
+RANLIB_TEST = [ -f /usr/bin/ranlib -o -f /bin/ranlib ]
+RANLIB = ranlib
+SHELL = /bin/sh
+INSTALL = $(srcdir)/install.sh -c
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL)
+MAKEINFO = makeinfo
+MAKEINFOFLAGS =
+TEXI2DVI = texi2dvi
+LN = ln -s
+
+#### host and target specific makefile fragments come in here.
+###
+
+SRCS = memory.c mp_set_fns.c mp_clz_tab.c version.c stack-alloc.c mp_bpl.c \
+ extract-double.c insert-double.c
+OBJS = memory.o mp_set_fns.o mp_clz_tab.o version.o stack-alloc.o mp_bpl.o \
+ extract-double.o insert-double.o
+FILES = gmp.h mp.h gmp-impl.h longlong.h urandom.h move-if-change \
+ mkinstalldirs INSTALL COPYING.LIB ChangeLog Makefile.in \
+ NEWS README SPEED TODO config.guess config.sub configure configure.in \
+ gmp.info* gmp.texi texinfo.tex $(SRCS)
+
+INCLUDES = -I. -Impn -I$(srcdir)
+FLAGS_TO_PASS = "CC=$(CC)" "CFLAGS=$(CFLAGS)" "XCFLAGS=$(XCFLAGS)"
+
+all: libgmp.a
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+libgmp.a: mpn/libmpn.a mpz/libmpz.a mpf/libmpf.a mpq/libmpq.a $(OBJS)
+ rm -rf tmpdir
+ mkdir tmpdir
+ for i in mpn mpz mpf mpq; \
+ do \
+ mkdir tmpdir/$$i; \
+ ( cd tmpdir/$$i; $(AR) x ../../$$i/lib$$i.a ); \
+ done
+ cp $(OBJS) tmpdir
+ cd tmpdir; $(AR) $(AR_FLAGS) $@ *.o */*.o
+ if $(RANLIB_TEST) ; then $(RANLIB) tmpdir/$@; else true; fi
+ mv tmpdir/$@ .
+ rm -rf tmpdir
+
+libmp.a: mpn/libmpn.a mpbsd/libmpbsd.a $(OBJS)
+ rm -rf tmpdir
+ mkdir tmpdir
+ for i in mpn mpbsd; \
+ do \
+ mkdir tmpdir/$$i; \
+ ( cd tmpdir/$$i; $(AR) x ../../$$i/lib$$i.a ); \
+ done
+ cp $(OBJS) tmpdir
+ cd tmpdir; $(AR) $(AR_FLAGS) $@ *.o */*.o
+ if $(RANLIB_TEST) ; then $(RANLIB) tmpdir/$@; else true; fi
+ mv tmpdir/$@ .
+ rm -rf tmpdir
+
+mpn/libmpn.a: force
+ cd mpn; $(MAKE) $(FLAGS_TO_PASS) libmpn.a
+mpz/libmpz.a: force
+ cd mpz; $(MAKE) $(FLAGS_TO_PASS) libmpz.a
+mpf/libmpf.a: force
+ cd mpf; $(MAKE) $(FLAGS_TO_PASS) libmpf.a
+mpq/libmpq.a: force
+ cd mpq; $(MAKE) $(FLAGS_TO_PASS) libmpq.a
+mpbsd/libmpbsd.a: force
+ cd mpbsd; $(MAKE) $(FLAGS_TO_PASS) libmpbsd.a
+
+check: libgmp.a
+ cd mpz/tests; $(MAKE) $(FLAGS_TO_PASS) check
+ cd mpq/tests; $(MAKE) $(FLAGS_TO_PASS) check
+ cd mpf/tests; $(MAKE) $(FLAGS_TO_PASS) check
+
+doc: gmp.dvi gmp.info
+
+info: $(srcdir)/gmp.info
+$(srcdir)/gmp.info: $(srcdir)/gmp.texi
+ cd $(srcdir); $(MAKEINFO) gmp.texi
+
+dvi: gmp.dvi
+gmp.dvi: $(srcdir)/gmp.texi
+ rm -f tmp.texi
+ $(LN) $(srcdir)/gmp.texi tmp.texi
+ TEXINPUTS=.:$(srcdir) $(TEXI2DVI) tmp.texi
+ rm -f tmp.texi
+ mv tmp.dvi gmp.dvi
+ rm -f tmp.*
+
+ps: gmp.ps
+gmp.ps: gmp.dvi
+ dvips gmp.dvi -o gmp.ps
+
+html: gmp_toc.html
+gmp_toc.html: $(srcdir)/gmp.texi
+ texi2html -acc -split_chapter $(srcdir)/gmp.texi
+
+# The semicolon is to prevent the install.sh -> install default rule
+# from doing anything. Having it run true helps avoid problems and
+# noise from versions of make which don't like to have null commands.
+install: install-normal ; @true
+
+install-strip: install-normal
+install-normal: installdirs libgmp.a gmp.info install-info-files
+ $(INSTALL_DATA) libgmp.a $(libdir)/libgmp.a
+ -chmod a-x $(libdir)/libgmp.a
+ $(INSTALL_DATA) $(srcdir)/gmp.h $(includedir)/gmp.h
+ -chmod a-x $(includedir)/gmp.h
+install-bsdmp: installdirs libmp.a gmp.info install-info-files
+ $(INSTALL_DATA) libmp.a $(libdir)/libmp.a
+ -chmod a-x $(libdir)/libmp.a
+ $(INSTALL_DATA) $(srcdir)/mp.h $(includedir)/mp.h
+ -chmod a-x $(includedir)/mp.h
+install-info-files: installdirs $(srcdir)/gmp.info
+ cd $(srcdir); for f in gmp.info*; \
+ do $(INSTALL_DATA) $$f $(infodir)/$$f; done
+ -chmod a-x $(infodir)/gmp.info*
+ # Attempt to edit the info directory node
+ if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
+ install-info --dir-file=$(infodir)/dir $(infodir)/gmp.info; \
+ else true; fi
+
+installdirs: $(srcdir)/mkinstalldirs
+ $(srcdir)/mkinstalldirs $(includedir) $(libdir) $(infodir)
+
+uninstall:
+ rm -f $(libdir)/libgmp.a
+ rm -f $(includedir)/gmp.h
+ rm -f $(libdir)/libmp.a
+ rm -f $(includedir)/mp.h
+ rm -f $(infodir)/gmp.info*
+
+clean mostlyclean:
+ rm -f *.o libgmp.a libmp.a gmp.dvi gmp.ps tmp.* tmp-*
+ rm -f gmp.?? gmp.??s gmp.log gmp.toc gmp.*aux gmp*.html
+ -cd mpn; $(MAKE) $@
+ -cd mpz; $(MAKE) $@
+ -cd mpf; $(MAKE) $@
+ -cd mpq; $(MAKE) $@
+ -cd mpbsd; $(MAKE) $@
+distclean: clean
+ rm -f Makefile config.status
+ -cd mpn; $(MAKE) $@
+ -cd mpz; $(MAKE) $@
+ -cd mpf; $(MAKE) $@
+ -cd mpq; $(MAKE) $@
+ -cd mpbsd; $(MAKE) $@
+maintainer-clean: distclean
+ rm -f $(srcdir)/gmp.info*
+
+TAGS: force
+ cd $(srcdir); etags *.[ch] mp*/*.c mpn/generic/*.c >TAGS
+
+dist:
+ @echo "sorry, not supported target"
+ @exit 1
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+ $(SHELL) ./config.status
+
+H = $(srcdir)/gmp.h $(srcdir)/gmp-impl.h mpn/gmp-mparam.h
+
+extract-double.o: $(srcdir)/extract-double.c $(H)
+insert-double.o: $(srcdir)/insert-double.c $(H)
+memory.o: $(srcdir)/memory.c $(H)
+mp_bpl.o: $(srcdir)/mp_bpl.c
+mp_clz_tab.o: $(srcdir)/mp_clz_tab.c
+mp_set_fns.o: $(srcdir)/mp_set_fns.c $(H)
+stack-alloc.o: $(srcdir)/stack-alloc.c $(srcdir)/stack-alloc.h
+version.o: $(srcdir)/version.c
+
+force:
+.PNONY: check install install-bsdmp install-info-files install-strip uninstall
+.PHONY: doc clean distclean maintainer-clean force info dvi
diff --git a/gnu/lib/libgmp/NEWS b/gnu/lib/libgmp/NEWS
new file mode 100644
index 0000000..b61c840
--- /dev/null
+++ b/gnu/lib/libgmp/NEWS
@@ -0,0 +1,56 @@
+NOTEWORTHY CHANGES IN GNU MP IN VERSION 2
+
+* Division routines in the mpz class have changed. There are three classes of
+ functions, that rounds the quotient to -infinity, 0, and +infinity,
+ respectively. The first class of functions have names that begin with
+ mpz_fdiv (f is short for floor), the second class' names begin with mpz_tdiv
+ (t is short for trunc), and the third class' names begin with mpz_cdiv (c is
+ short for ceil).
+
+ The old division routines beginning with mpz_m are similar to the new
+ mpz_fdiv, with the exception that some of the new functions return useful
+ values.
+
+ The old function names can still be used. All the old functions names will
+ now do floor division, not trunc division as some of them used to. This was
+ changed to make the functions more compatible with common mathematical
+ practice.
+
+ The mpz_mod and mpz_mod_ui functions now compute the mathematical mod
+ function. I.e., the sign of the 2nd argument is ignored.
+
+* The mpq assignment functions do not canonicalize their results. A new
+ function, mpq_canonicalize must be called by the user if the result is not
+ known to be canonical.
+* The mpn functions are now documented. These functions are intended for
+ very time critical applications, or applications that need full control over
+ memory allocation. Note that the mpn interface is irregular and hard to
+ use.
+* New functions for arbitrary precision floating point arithmetic. Names
+ begin with `mpf_'. Associated type mpf_t.
+* New and improved mpz functions, including much faster GCD, fast exact
+ division (mpz_divexact), bit scan (mpz_scan0 and mpz_scan1), and number
+ theoretical functions like Jacobi (mpz_jacobi) and multiplicative inverse
+ (mpz_invert).
+* New variable types (mpz_t and mpq_t) are available that makes syntax of
+ mpz and mpq calls nicer (no need for & before variables). The MP_INT and
+ MP_RAT types are still available for compatibility.
+* Uses GNU configure. This makes it possible to choose target architecture
+ and CPU variant, and to compile into a separate object directory.
+* Carefully optimized assembly for important inner loops. Support for DEC
+ Alpha, Amd 29000, HPPA 1.0 and 1.1, Intel pentium and generic x86, Intel
+ i960, Motorola MC68000, MC68020, MC88100, and MC88110, Motorola/IBM
+ PowerPC, National NS32000, IBM POWER, MIPS R3000, R4000, SPARCv7,
+ SuperSPARC, generic SPARCv8, and DEC VAX. Some support also for ARM,
+ Clipper, IBM ROMP (RT), and Pyramid AP/XP.
+* Faster. Thanks to the assembler code, new algorithms, and general tuning.
+ In particular, the speed on machines without GCC is improved.
+* Support for machines without alloca.
+* Now under the LGPL.
+
+INCOMPATIBILITIES BETWEEN GMP 1 AND GMP 2
+
+* mpq assignment functions do not canonicalize their results.
+* mpz division functions round differently.
+* mpz mod functions now really compute mod.
+* mpz_powm and mpz_powm_ui now really use mod for reduction.
diff --git a/gnu/lib/libgmp/PROJECTS b/gnu/lib/libgmp/PROJECTS
new file mode 100644
index 0000000..75016bd
--- /dev/null
+++ b/gnu/lib/libgmp/PROJECTS
@@ -0,0 +1,270 @@
+IDEAS ABOUT THINGS TO WORK ON
+
+* mpq_cmp: Maybe the most sensible thing to do would be to multiply the, say,
+ 4 most significant limbs of each operand and compare them. If that is not
+ sufficient, do the same for 8 limbs, etc.
+
+* Write mpi, the Multiple Precision Interval Arithmetic layer.
+
+* Write `mpX_eval' that take lambda-like expressions and a list of operands.
+
+* As a general rule, recognize special operand values in mpz and mpf, and
+ use shortcuts for speed. Examples: Recognize (small or all) 2^n in
+ multiplication and division. Recognize small bases in mpz_pow_ui.
+
+* Implement lazy allocation? mpz->d == 0 would mean no allocation made yet.
+
+* Maybe store one-limb numbers according to Per Bothner's idea:
+ struct {
+ mp_ptr d;
+ union {
+ mp_limb val; /* if (d == NULL). */
+ mp_size size; /* Length of data array, if (d != NULL). */
+ } u;
+ };
+ Problem: We can't normalize to that format unless we free the space
+ pointed to by d, and therefore small values will not be stored in a
+ canonical way.
+
+* Document complexity of all functions.
+
+* Add predicate functions mpz_fits_signedlong_p, mpz_fits_unsignedlong_p,
+ mpz_fits_signedint_p, etc.
+
+ mpz_floor (mpz, mpq), mpz_trunc (mpz, mpq), mpz_round (mpz, mpq).
+
+* Better random number generators. There should be fast (like mpz_random),
+ very good (mpz_veryrandom), and special purpose (like mpz_random2). Sizes
+ in *bits*, not in limbs.
+
+* It'd be possible to have an interface "s = add(a,b)" with automatic GC.
+ If the mpz_xinit routine remembers the address of the variable we could
+ walk-and-mark the list of remembered variables, and free the space
+ occupied by the remembered variables that didn't get marked. Fairly
+ standard.
+
+* Improve speed for non-gcc compilers by defining umul_ppmm, udiv_qrnnd,
+ etc, to call __umul_ppmm, __udiv_qrnnd. A typical definition for
+ umul_ppmm would be
+ #define umul_ppmm(ph,pl,m0,m1) \
+ {unsigned long __ph; (pl) = __umul_ppmm (&__ph, (m0), (m1)); (ph) = __ph;}
+ In order to maintain just one version of longlong.h (gmp and gcc), this
+ has to be done outside of longlong.h.
+
+Bennet Yee at CMU proposes:
+* mpz_{put,get}_raw for memory oriented I/O like other *_raw functions.
+* A function mpfatal that is called for exceptions. Let the user override
+ a default definition.
+
+* Make all computation mpz_* functions return a signed int indicating if the
+ result was zero, positive, or negative?
+
+* Implement mpz_cmpabs, mpz_xor, mpz_to_double, mpz_to_si, mpz_lcm, mpz_dpb,
+ mpz_ldb, various bit string operations. Also mpz_@_si for most @??
+
+* Add macros for looping efficiently over a number's limbs:
+ MPZ_LOOP_OVER_LIMBS_INCREASING(num,limb)
+ { user code manipulating limb}
+ MPZ_LOOP_OVER_LIMBS_DECREASING(num,limb)
+ { user code manipulating limb}
+
+Brian Beuning proposes:
+ 1. An array of small primes
+ 3. A function to factor a mpz_t. [How do we return the factors? Maybe
+ we just return one arbitrary factor? In the latter case, we have to
+ use a data structure that records the state of the factoring routine.]
+ 4. A routine to look for "small" divisors of an mpz_t
+ 5. A 'multiply mod n' routine based on Montgomery's algorithm.
+
+Dough Lea proposes:
+ 1. A way to find out if an integer fits into a signed int, and if so, a
+ way to convert it out.
+ 2. Similarly for double precision float conversion.
+ 3. A function to convert the ratio of two integers to a double. This
+ can be useful for mixed mode operations with integers, rationals, and
+ doubles.
+
+Elliptic curve method description in the Chapter `Algorithms in Number
+Theory' in the Handbook of Theoretical Computer Science, Elsevier,
+Amsterdam, 1990. Also in Carl Pomerance's lecture notes on Cryptology and
+Computational Number Theory, 1990.
+
+* Harald Kirsh suggests:
+ mpq_set_str (MP_RAT *r, char *numerator, char *denominator).
+
+* New function: mpq_get_ifstr (int_str, frac_str, base,
+ precision_in_som_way, rational_number). Convert RATIONAL_NUMBER to a
+ string in BASE and put the integer part in INT_STR and the fraction part
+ in FRAC_STR. (This function would do a division of the numerator and the
+ denominator.)
+
+* Should mpz_powm* handle negative exponents?
+
+* udiv_qrnnd: If the denominator is normalized, the n0 argument has very
+ little effect on the quotient. Maybe we can assume it is 0, and
+ compensate at a later stage?
+
+* Better sqrt: First calculate the reciprocal square root, then multiply by
+ the operand to get the square root. The reciprocal square root can be
+ obtained through Newton-Raphson without division. To compute sqrt(A), the
+ iteration is,
+
+ 2
+ x = x (3 - A x )/2.
+ i+1 i i
+
+ The final result can be computed without division using,
+
+ sqrt(A) = A x .
+ n
+
+* Newton-Raphson using multiplication: We get twice as many correct digits
+ in each iteration. So if we square x(k) as part of the iteration, the
+ result will have the leading digits in common with the entire result from
+ iteration k-1. A _mpn_mul_lowpart could help us take advantage of this.
+
+* Peter Montgomery: If 0 <= a, b < p < 2^31 and I want a modular product
+ a*b modulo p and the long long type is unavailable, then I can write
+
+ typedef signed long slong;
+ typedef unsigned long ulong;
+ slong a, b, p, quot, rem;
+
+ quot = (slong) (0.5 + (double)a * (double)b / (double)p);
+ rem = (slong)((ulong)a * (ulong)b - (ulong)p * (ulong)quot);
+ if (rem < 0} {rem += p; quot--;}
+
+* Speed modulo arithmetic, using Montgomery's method or my pre-inversion
+ method. In either case, special arithmetic calls would be needed,
+ mpz_mmmul, mpz_mmadd, mpz_mmsub, plus some kind of initialization
+ functions. Better yet: Write a new mpr layer.
+
+* mpz_powm* should not use division to reduce the result in the loop, but
+ instead pre-compute the reciprocal of the MOD argument and do reduced_val
+ = val-val*reciprocal(MOD)*MOD, or use Montgomery's method.
+
+* mpz_mod_2expplussi -- to reduce a bignum modulo (2**n)+s
+
+* It would be a quite important feature never to allocate more memory than
+ really necessary for a result. Sometimes we can achieve this cheaply, by
+ deferring reallocation until the result size is known.
+
+* New macro in longlong.h: shift_rhl that extracts a word by shifting two
+ words as a unit. (Supported by i386, i860, HP-PA, POWER, 29k.) Useful
+ for shifting multiple precision numbers.
+
+* The installation procedure should make a test run of multiplication to
+ decide the threshold values for algorithm switching between the available
+ methods.
+
+* Fast output conversion of x to base B:
+ 1. Find n, such that (B^n > x).
+ 2. Set y to (x*2^m)/(B^n), where m large enough to make 2^n ~~ B^n
+ 3. Multiply the low half of y by B^(n/2), and recursively convert the
+ result. Truncate the low half of y and convert that recursively.
+ Complexity: O(M(n)log(n))+O(D(n))!
+
+* Improve division using Newton-Raphson. Check out "Newton Iteration and
+ Integer Division" by Stephen Tate in "Synthesis of Parallel Algorithms",
+ Morgan Kaufmann, 1993 ("beware of some errors"...)
+
+* Improve implementation of Karatsuba's algorithm. For most operand sizes,
+ we can reduce the number of operations by splitting differently.
+
+* Faster multiplication: The best approach is to first implement Toom-Cook.
+ People report that it beats Karatsuba's algorithm already at about 100
+ limbs. FFT would probably never beat a well-written Toom-Cook (not even for
+ millions of bits).
+
+FFT:
+{
+ * Multiplication could be done with Montgomery's method combined with
+ the "three primes" method described in Lipson. Maybe this would be
+ faster than to Nussbaumer's method with 3 (simple) moduli?
+
+ * Maybe the modular tricks below are not needed: We are using very
+ special numbers, Fermat numbers with a small base and a large exponent,
+ and maybe it's possible to just subtract and add?
+
+ * Modify Nussbaumer's convolution algorithm, to use 3 words for each
+ coefficient, calculating in 3 relatively prime moduli (e.g.
+ 0xffffffff, 0x100000000, and 0x7fff on a 32-bit computer). Both all
+ operations and CRR would be very fast with such numbers.
+
+ * Optimize the Schoenhage-Stassen multiplication algorithm. Take advantage
+ of the real valued input to save half of the operations and half of the
+ memory. Use recursive FFT with large base cases, since recursive FFT has
+ better memory locality. A normal FFT get 100% cache misses for large
+ enough operands.
+
+ * In the 3-prime convolution method, it might sometimes be a win to use 2,
+ 3, or 5 primes. Imagine that using 3 primes would require a transform
+ length of 2^n. But 2 primes might still sometimes give us correct
+ results with that same transform length, or 5 primes might allow us to
+ decrease the transform size to 2^(n-1).
+
+ To optimize floating-point based complex FFT we have to think of:
+
+ 1. The normal implementation accesses all input exactly once for each of
+ the log(n) passes. This means that we will get 0% cache hit when n >
+ our cache. Remedy: Reorganize computation to compute partial passes,
+ maybe similar to a standard recursive FFT implementation. Use a large
+ `base case' to make any extra overhead of this organization negligible.
+
+ 2. Use base-4, base-8 and base-16 FFT instead of just radix-2. This can
+ reduce the number of operations by 2x.
+
+ 3. Inputs are real-valued. According to Knuth's "Seminumerical
+ Algorithms", exercise 4.6.4-14, we can save half the memory and half
+ the operations if we take advantage of that.
+
+ 4. Maybe make it possible to write the innermost loop in assembly, since
+ that could win us another 2x speedup. (If we write our FFT to avoid
+ cache-miss (see #1 above) it might be logical to write the `base case'
+ in assembly.)
+
+ 5. Avoid multiplication by 1, i, -1, -i. Similarly, optimize
+ multiplication by (+-\/2 +- i\/2).
+
+ 6. Put as many bits as possible in each double (but don't waste time if
+ that doesn't make the transform size become smaller).
+
+ 7. For n > some large number, we will get accuracy problems because of the
+ limited precision of our floating point arithmetic. This can easily be
+ solved by using the Karatsuba trick a few times until our operands
+ become small enough.
+
+ 8. Precompute the roots-of-unity and store them in a vector.
+}
+
+* When a division result is going to be just one limb, (i.e. nsize-dsize is
+ small) normalization could be done in the division loop.
+
+* Never allocate temporary space for a source param that overlaps with a
+ destination param needing reallocation. Instead malloc a new block for
+ the destination (and free the source before returning to the caller).
+
+* Parallel addition. Since each processors have to tell it is ready to the
+ next processor, we can use simplified synchronization, and actually write
+ it in C: For each processor (apart from the least significant):
+
+ while (*svar != my_number)
+ ;
+ *svar = my_number + 1;
+
+ The least significant processor does this:
+
+ *svar = my_number + 1; /* i.e., *svar = 1 */
+
+ Before starting the addition, one processor has to store 0 in *svar.
+
+ Other things to think about for parallel addition: To avoid false
+ (cache-line) sharing, allocate blocks on cache-line boundaries.
+
+
+Local Variables:
+mode: text
+fill-column: 77
+fill-prefix: " "
+version-control: never
+End:
diff --git a/gnu/lib/libgmp/README b/gnu/lib/libgmp/README
new file mode 100644
index 0000000..3afa677
--- /dev/null
+++ b/gnu/lib/libgmp/README
@@ -0,0 +1,137 @@
+ THE GNU MP LIBRARY
+
+
+GNU MP is a library for arbitrary precision arithmetic, operating on signed
+integers, rational numbers, and floating point numbers. It has a rich set
+of functions, and the functions have a regular interface.
+
+GNU MP is designed to be as fast as possible, both for small operands and for
+huge operands. The speed is achieved by using fullwords as the basic
+arithmetic type, by using fast algorithms, by carefully optimized assembly
+code for the most common inner loops for a lots of CPUs, and by a general
+emphasis on speed (instead of simplicity or elegance).
+
+The speed of GNU MP is believed to be faster than any other similar library.
+The advantage for GNU MP increases with the operand sizes for certain
+operations, since GNU MP in many cases has asymptotically faster algorithms.
+
+
+ GETTING STARTED
+
+First, you have to configure and compiler GNU MP. Simply typing
+
+ ./configure; make
+
+will normally do a reasonable job, but will not give optimal library
+execution speed. So unless you're very unpatient, please read the detailed
+instructions in the file INSTALL or in gmp.texi.
+
+Once you have compiled the library, you should write some small example, and
+make sure you can compile them. A typical compilation command is this:
+
+ gcc -g your-file.c -I<gmp-source-dir> <gmp-bin-dir>libgmp.a -lm
+
+If you have installed the library, you can simply do:
+
+ gcc -g your-file.c -lgmp -lm
+
+The -lm is normally not needed, since only a few functions in GNU MP use the
+math library.
+
+Here is a sample program that declares 2 variables, initializes them as
+required, and sets one of them from a signed integer, and the other from a
+string of digits. It then prints the product of the two numbers in base 10.
+
+ #include <stdio.h>
+ #include "gmp.h"
+
+ main ()
+ {
+ mpz_t a, b, p;
+
+ mpz_init (a); /* initialize variables */
+ mpz_init (b);
+ mpz_init (p);
+
+ mpz_set_si (a, 756839); /* assign variables */
+ mpz_set_str (b, "314159265358979323846", 0);
+ mpz_mul (p, a, b); /* generate product */
+ mpz_out_str (stdout, 10, p); /* print number without newline */
+ puts (""); /* print newline */
+
+ mpz_clear (a); /* clear out variables */
+ mpz_clear (b);
+ mpz_clear (p);
+
+ exit (0);
+ }
+
+This might look tedious, with all initializing and clearing. Fortunately
+some of these operations can be combined, and other operations can often be
+avoided. The example above would be written differently by an experienced
+GNU MP user:
+
+ #include <stdio.h>
+ #include "gmp.h"
+
+ main ()
+ {
+ mpz_t b, p;
+
+ mpz_init (p);
+
+ mpz_init_set_str (b, "314159265358979323846", 0);
+ mpz_mul_ui (p, b, 756839); /* generate product */
+ mpz_out_str (stdout, 10, p); /* print number without newline */
+ puts (""); /* print newline */
+
+ exit (0);
+ }
+
+
+ OVERVIEW OF GNU MP
+
+There are five classes of functions in GNU MP.
+
+ 1. Signed integer arithmetic functions, mpz_*. These functions are intended
+ to be easy to use, with their regular interface. The associated type is
+ `mpz_t'.
+
+ 2. Rational arithmetic functions, mpq_*. For now, just a small set of
+ functions necessary for basic rational arithmetics. The associated type
+ is `mpq_t'.
+
+ 3. Floating-point arithmetic functions, mpf_*. If the C type `double'
+ doesn't give enough precision for your application, declare your
+ variables as `mpf_t' instead, set the precision to any number desired,
+ and call the functions in the mpf class for the arithmetic operations.
+
+ 4. Positive-integer, hard-to-use, very low overhead functions are in the
+ mpn_* class. No memory management is performed. The caller must ensure
+ enough space is available for the results. The set of functions is not
+ regular, nor is the calling interface. These functions accept input
+ arguments in the form of pairs consisting of a pointer to the least
+ significant word, and a integral size telling how many limbs (= words)
+ the pointer points to.
+
+ Almost all calculations, in the entire package, are made by calling these
+ low-level functions.
+
+ 5. Berkeley MP compatible functions.
+
+ To use these functions, include the file "mp.h". You can test if you are
+ using the GNU version by testing if the symbol __GNU_MP__ is defined.
+
+For more information on how to use GNU MP, please refer to the documentation.
+It is composed from the file gmp.texi, and can be displayed on the screen or
+printed. How to do that, as well how to build the library, is described in
+the INSTALL file in this directory.
+
+
+ REPORTING BUGS
+
+If you find a bug in the library, please make sure to tell us about it!
+
+Report bugs and propose modifications and enhancements to
+bug-gmp@prep.ai.mit.edu. What information is needed in a good bug report is
+described in the manual.
diff --git a/gnu/lib/libgmp/SPEED b/gnu/lib/libgmp/SPEED
new file mode 100644
index 0000000..e888e17
--- /dev/null
+++ b/gnu/lib/libgmp/SPEED
@@ -0,0 +1,156 @@
+==============================================================================
+Cycle counts and throughput for low-level routines in GNU MP as currently
+implemented.
+
+A range means that the timing is data-dependent. The slower number of such
+an interval is usually the best performance estimate.
+
+The throughput value, measured in Gb/s (gigabits per second) has a meaning
+only for comparison between CPUs.
+
+A star before a line means that all values on that line are estimates. A
+star before a number means that that number is an estimate. A `p' before a
+number means that the code is not complete, but the timing is believed to be
+accurate.
+
+ | mpn_lshift mpn_add_n mpn_mul_1 mpn_addmul_1
+ | mpn_rshift mpn_sub_n mpn_submul_1
+------------+-----------------------------------------------------------------
+DEC/Alpha |
+EV4 | 4.75 cycles/64b 7.75 cycles/64b 42 cycles/64b 42 cycles/64b
+ 200MHz | 2.7 Gb/s 1.65 Gb/s 20 Gb/s 20 Gb/s
+EV5 old code| 4.0 cycles/64b 5.5 cycles/64b 18 cycles/64b 18 cycles/64b
+ 267MHz | 4.27 Gb/s 3.10 Gb/s 61 Gb/s 61 Gb/s
+ 417MHz | 6.67 Gb/s 4.85 Gb/s 95 Gb/s 95 Gb/s
+EV5 tuned | 3.25 cycles/64b 4.75 cycles/64b
+ 267MHz | 5.25 Gb/s 3.59 Gb/s as above
+ 417MHz | 8.21 Gb/s 5.61 Gb/s
+------------+-----------------------------------------------------------------
+Sun/SPARC |
+SPARC v7 | 14.0 cycles/32b 8.5 cycles/32b 37-54 cycl/32b 37-54 cycl/32b
+SuperSPARC | 3 cycles/32b 2.5 cycles/32b 8.2 cycles/32b 10.8 cycles/32b
+ 50MHz | 0.53 Gb/s 0.64 Gb/s 6.2 Gb/s 4.7 Gb/s
+**SuperSPARC| tuned addmul and submul will take: 9.25 cycles/32b
+MicroSPARC2 | ? 6.65 cycles/32b 30 cycles/32b 31.5 cycles/32b
+ 110MHz | ? 0.53 Gb/s 3.75 Gb/s 3.58 Gb/s
+SuperSPARC2 | ? ? ? ?
+Ultra/32 (4)| 2.5 cycles/32b 6.5 cycles/32b 13-27 cyc/32b 16-30 cyc/32b
+ 182MHz | 2.33 Gb/s 0.896 Gb/s 14.3-6.9 Gb/s
+Ultra/64 (5)| 2.5 cycles/64b 10 cycles/64b 40-70 cyc/64b 46-76 cyc/64b
+ 182MHz | 4.66 Gb/s 1.16 Gb/s 18.6-11 Gb/s
+HalSPARC64 | ? ? ? ?
+------------+-----------------------------------------------------------------
+SGI/MIPS |
+R3000 | 6 cycles/32b 9.25 cycles/32b 16 cycles/32b 16 cycles/32b
+ 40MHz | 0.21 Gb/s 0.14 Gb/s 2.56 Gb/s 2.56 Gb/s
+R4400/32 | 8.6 cycles/32b 10 cycles/32b 16-18 19-21
+ 200MHz | 0.74 Gb/s 0.64 Gb/s 13-11 Gb/s 11-9.6 Gb/s
+*R4400/64 | 8.6 cycles/64b 10 cycles/64b 22 cycles/64b 22 cycles/64b
+ *200MHz | 1.48 Gb/s 1.28 Gb/s 37 Gb/s 37 Gb/s
+R4600/32 | 6 cycles/64b 9.25 cycles/32b 15 cycles/32b 19 cycles/32b
+ 134MHz | 0.71 Gb/s 0.46 Gb/s 9.1 Gb/s 7.2 Gb/s
+R4600/64 | 6 cycles/64b 9.25 cycles/64b ? ?
+ 134MHz | 1.4 Gb/s 0.93 Gb/s ? ?
+R8000/64 | 3 cycles/64b 4.6 cycles/64b 8 cycles/64b 8 cycles/64b
+ 75MHz | 1.6 Gb/s 1.0 Gb/s 38 Gb/s 38 Gb/s
+*R10000/64 | 2 cycles/64b 3 cycles/64b 11 cycles/64b 11 cycles/64b
+ *200MHz | 6.4 Gb/s 4.27 Gb/s 74 Gb/s 74 Gb/s
+ *250MHz | 8.0 Gb/s 5.33 Gb/s 93 Gb/s 93 Gb/s
+------------+-----------------------------------------------------------------
+Motorola |
+MC68020 | ? 24 cycles/32b 62 cycles/32b 70 cycles/32b
+MC68040 | ? 6 cycles/32b 24 cycles/32b 25 cycles/32b
+MC88100 | >5 cycles/32b 4.6 cycles/32b 16/21 cyc/32b p 18/23 cyc/32b
+MC88110 wt | ? 3.75 cycles/32b 6 cycles/32b 8.5 cyc/32b
+*MC88110 wb | ? 2.25 cycles/32b 4 cycles/32b 5 cycles/32b
+------------+-----------------------------------------------------------------
+HP/PA-RISC |
+PA7000 | 4 cycles/32b 5 cycles/32b 9 cycles/32b 11 cycles/32b
+ 67MHz | 0.53 Gb/s 0.43 Gb/s 7.6 Gb/s 6.2 Gb/s
+PA7100 | 3.25 cycles/32b 4.25 cycles/32b 7 cycles/32b 8 cycles/32b
+ 99MHz | 0.97 Gb/s 0.75 Gb/s 14 Gb/s 12.8 Gb/s
+PA7100LC | ? ? ? ?
+PA7200 (3) | 3 cycles/32b 4 cycles/32b 7 cycles/32b 6.5 cycles/32b
+ 100MHz | 1.07 Gb/s 0.80 14 Gb/s 15.8 Gb/s
+PA7300LC | ? ? ? ?
+*PA8000 | 3 cycles/64b 4 cycles/64b 7 cycles/64b 6.5 cycles/64b
+ 180MHz | 3.84 Gb/s 2.88 Gb/s 105 Gb/s 113 Gb/s
+------------+-----------------------------------------------------------------
+Intel/x86 |
+386DX | 20 cycles/32b 17 cycles/32b 41-70 cycl/32b 50-79 cycl/32b
+ 16.7MHz | 0.027 Gb/s 0.031 Gb/s 0.42-0.24 Gb/s 0.34-0.22 Gb/s
+486DX | ? ? ? ?
+486DX4 | 9.5 cycles/32b 9.25 cycles/32b 17-23 cycl/32b 20-26 cycl/32b
+ 100MHz | 0.34 Gb/s 0.35 Gb/s 6.0-4.5 Gb/s 5.1-3.9 Gb/s
+Pentium | 2/6 cycles/32b 2.5 cycles/32b 13 cycles/32b 14 cycles/32b
+ 167MHz | 2.7/0.89 Gb/s 2.1 Gb/s 13.1 Gb/s 12.2 Gb/s
+Pentium Pro | 2.5 cycles/32b 3.5 cycles/32b 6 cycles/32b 9 cycles/32b
+ 200MHz | 2.6 Gb/s 1.8 Gb/s 34 Gb/s 23 Gb/s
+------------+-----------------------------------------------------------------
+IBM/POWER |
+RIOS 1 | 3 cycles/32b 4 cycles/32b 11.5-12.5 c/32b 14.5/15.5 c/32b
+RIOS 2 | 2 cycles/32b 2 cycles/32b 7 cycles/32b 8.5 cycles/32b
+------------+-----------------------------------------------------------------
+PowerPC |
+PPC601 (1) | 3 cycles/32b 6 cycles/32b 11-16 cycl/32b 14-19 cycl/32b
+PPC601 (2) | 5 cycles/32b 6 cycles/32b 13-22 cycl/32b 16-25 cycl/32b
+ 67MHz (2) | 0.43 Gb/s 0.36 Gb/s 5.3-3.0 Gb/s 4.3-2.7 Gb/s
+PPC603 | ? ? ? ?
+*PPC604 | 2 3 2 3
+ *167MHz | 57 Gb/s
+PPC620 | ? ? ? ?
+------------+-----------------------------------------------------------------
+Tege |
+Model 1 | 2 cycles/64b 3 cycles/64b 2 cycles/64b 3 cycles/64b
+ 250MHz | 8 Gb/s 5.3 Gb/s 500 Gb/s 340 Gb/s
+ 500MHz | 16 Gb/s 11 Gb/s 1000 Gb/s 680 Gb/s
+____________|_________________________________________________________________
+(1) Using POWER and PowerPC instructions
+(2) Using only PowerPC instructions
+(3) Actual timing for shift/add/sub depends on code alignment. PA7000 code
+ is smaller and therefore often faster on this CPU.
+(4) Multiplication routines modified for bogus UltraSPARC early-out
+ optimization. Smaller operand is put in rs1, not rs2 as it should
+ according to the SPARC architecture manuals.
+(5) Preliminary timings, since there is no stable 64-bit environment.
+(6) Use mulu.d at least for mpn_lshift. With mak/extu/or, we can only get
+ to 2 cycles/32b.
+
+=============================================================================
+Estimated theoretical asymptotic cycle counts for low-level routines:
+
+ | mpn_lshift mpn_add_n mpn_mul_1 mpn_addmul_1
+ | mpn_rshift mpn_sub_n mpn_submul_1
+------------+-----------------------------------------------------------------
+DEC/Alpha |
+EV4 | 3 cycles/64b 5 cycles/64b 42 cycles/64b 42 cycles/64b
+EV5 | 3 cycles/64b 4 cycles/64b 18 cycles/64b 18 cycles/64b
+------------+-----------------------------------------------------------------
+Sun/SPARC |
+SuperSPARC | 2.5 cycles/32b 2 cycles/32b 8 cycles/32b 9 cycles/32b
+------------+-----------------------------------------------------------------
+SGI/MIPS |
+R4400/32 | 5 cycles/64b 8 cycles/64b 16 cycles/64b 16 cycles/64b
+R4400/64 | 5 cycles/64b 8 cycles/64b 22 cycles/64b 22 cycles/64b
+R4600 |
+------------+-----------------------------------------------------------------
+HP/PA-RISC |
+PA7100 | 3 cycles/32b 4 cycles/32b 6.5 cycles/32b 7.5 cycles/32b
+PA7100LC |
+------------+-----------------------------------------------------------------
+Motorola |
+MC88110 | 1.5 cyc/32b (6) 1.5 cycle/32b 1.5 cycles/32b 2.25 cycles/32b
+------------+-----------------------------------------------------------------
+Intel/x86 |
+486DX4 |
+Pentium P5x | 5 cycles/32b 2 cycles/32b 11.5 cycles/32b 13 cycles/32b
+Pentium Pro | 2 cycles/32b 3 cycles/32b 4 cycles/32b 6 cycles/32b
+------------+-----------------------------------------------------------------
+IBM/POWER |
+RIOS 1 | 3 cycles/32b 4 cycles/32b
+RIOS 2 | 1.5 cycles/32b 2 cycles/32b 4.5 cycles/32b 5.5 cycles/32b
+------------+-----------------------------------------------------------------
+PowerPC |
+PPC601 (1) | 3 cycles/32b ?4 cycles/32b
+PPC601 (2) | 4 cycles/32b ?4 cycles/32b
+____________|_________________________________________________________________
diff --git a/gnu/lib/libgmp/TODO b/gnu/lib/libgmp/TODO
new file mode 100644
index 0000000..6612d8b
--- /dev/null
+++ b/gnu/lib/libgmp/TODO
@@ -0,0 +1,184 @@
+THINGS TO WORK ON
+
+Note that many of these things mentioned here are already fixed in GMP 2.0.
+
+* Improve speed for non-gcc compilers by defining umul_ppmm, udiv_qrnnd,
+ etc, to call __umul_ppmm, __udiv_qrnnd. A typical definition for
+ umul_ppmm would be
+ #define umul_ppmm(ph,pl,m0,m1) \
+ {unsigned long __ph; (pl) = __umul_ppmm (&__ph, (m0), (m1)); (ph) = __ph;}
+ In order to maintain just one version of longlong.h (gmp and gcc), this
+ has to be done outside of longlong.h.
+
+* Change mpn-routines to not deal with normalisation?
+ mpn_add: Unchanged.
+ mpn_sub: Remove normalization loop. Does it assume normalised input?
+ mpn_mul: Make it return most sign limb, to simplify normalisation.
+ Karatsubas algorith will be greatly simplified if mpn_add and
+ mpn_sub doesn't normalise their results.
+ mpn_div: Still requires strict normalisation.
+ Beware of problems with mpn_cmp (and similar), a larger size does not
+ ensure that an operand is larger, since it may be "less normalised".
+ Normalization has to be moved into mpz-functions.
+
+Bennet Yee at CMU proposes:
+* mpz_{put,get}_raw for memory oriented I/O like other *_raw functions.
+* A function mpfatal that is called for exceptions. The user may override
+ the default definition.
+
+* mout should group in 10-digit groups.
+* ASCII dependence?
+* Error reporting from I/O functions (linkoping)?
+
+* Make all computation mpz_* functions return a signed int indicating if
+ the result was zero, positive, or negative?
+
+* Implement mpz_cmpabs, mpz_xor, mpz_to_double, mpz_to_si, mpz_lcm,
+ mpz_dpb, mpz_ldb, various bit string operations like mpz_cntbits. Also
+ mpz_@_si for most @??
+
+Brian Beuning proposes:
+ 1. An array of small primes
+ 3. A function to factor an MINT
+ 4. A routine to look for "small" divisors of an MINT
+ 5. A 'multiply mod n' routine based on Montgomery's algorithm.
+
+Doug Lea proposes:
+ 1. A way to find out if an integer fits into a signed int, and if so, a
+ way to convert it out.
+ 2. Similarly for double precision float conversion.
+ 3. A function to convert the ratio of two integers to a double. This
+ can be useful for mixed mode operations with integers, rationals, and
+ doubles.
+ 5. Bit-setting, clearing, and testing operations, as in
+ mpz_setbit(MP_INT* dest, MP_INT* src, unsigned long bit_number),
+ and used, for example in
+ mpz_setbit(x, x, 123)
+ to directly set the 123rd bit of x.
+ If these are supported, you don't first have to set up
+ an otherwise unnecessary mpz holding a shifted value, then
+ do an "or" operation.
+
+Elliptic curve method descrition in the Chapter `Algorithms in Number
+Theory' in the Handbook of Theoretical Computer Science, Elsevier,
+Amsterdam, 1990. Also in Carl Pomerance's lecture notes on Cryptology and
+Computational Number Theory, 1990.
+
+* New function: mpq_get_ifstr (int_str, frac_str, base,
+ precision_in_som_way, rational_number). Convert RATIONAL_NUMBER to a
+ string in BASE and put the integer part in INT_STR and the fraction part
+ in FRAC_STR. (This function would do a division of the numerator and the
+ denominator.)
+
+* Should mpz_powm* handle negative exponents?
+
+* udiv_qrnnd: If the denominator is normalized, the n0 argument has very
+ little effect on the quotient. Maybe we can assume it is 0, and
+ compensate at a later stage?
+
+* Better sqrt: First calculate the reciprocal square root, then multiply by
+ the operand to get the square root. The reciprocal square root can be
+ obtained through Newton-Raphson without division. The iteration is x :=
+ x*(3-a*x^2)/2, where a is the operand.
+
+* Newton-Raphson using multiplication: We get twice as many correct digits
+ in each iteration. So if we square x(k) as part of the iteration, the
+ result will have the leading digits in common with the entire result from
+ iteration k-1. A _mpn_mul_lowpart could implement this.
+
+* Peter Montgomery: If 0 <= a, b < p < 2^31 and I want a modular product
+ a*b modulo p and the long long type is unavailable, then I can write
+
+ typedef signed long slong;
+ typedef unsigned long ulong;
+ slong a, b, p, quot, rem;
+
+ quot = (slong) (0.5 + (double)a * (double)b / (double)p);
+ rem = (slong)((ulong)a * (ulong)b - (ulong)p * (ulong)q);
+ if (rem < 0} {rem += p; quot--;}
+
+FFT:
+{
+ * Multiplication could be done with Montgomery's method combined with
+ the "three primes" method described in Lipson. Maybe this would be
+ faster than to Nussbaumer's method with 3 (simple) moduli?
+
+ * Maybe the modular tricks below are not needed: We are using very
+ special numbers, Fermat numbers with a small base and a large exponent,
+ and maybe it's possible to just subtract and add?
+
+ * Modify Nussbaumer's convolution algorithm, to use 3 words for each
+ coefficient, calculating in 3 relatively prime moduli (e.g.
+ 0xffffffff, 0x100000000, and 0x7fff on a 32-bit computer). Both all
+ operations and CRR would be very fast with such numbers.
+
+ * Optimize the Shoenhage-Stassen multiplication algorithm. Take
+ advantage of the real valued input to save half of the operations and
+ half of the memory. Try recursive variants with large, optimized base
+ cases. Use recursive FFT with large base cases, since recursive FFT
+ has better memory locality. A normal FFT get 100% cache miss.
+}
+
+* Speed modulo arithmetic, using Montgomery's method or my pre-invertion
+ method. In either case, special arithmetic calls would be needed,
+ mpz_mmmul, mpz_mmadd, mpz_mmsub, plus some kind of initialization
+ functions.
+
+* mpz_powm* should not use division to reduce the result in the loop, but
+ instead pre-compute the reciprocal of the MOD argument and do reduced_val
+ = val-val*reciprocal(MOD)*MOD, or use Montgomery's method.
+
+* mpz_mod_2expplussi -- to reduce a bignum modulo (2**n)+s
+
+* It would be a quite important feature never to allocate more memory than
+ really necessary for a result. Sometimes we can achieve this cheaply, by
+ deferring reallocation until the result size is known.
+
+* New macro in longlong.h: shift_rhl that extracts a word by shifting two
+ words as a unit. (Supported by i386, i860, HP-PA, RS6000, 29k.) Useful
+ for shifting multiple precision numbers.
+
+* The installation procedure should make a test run of multiplication to
+ decide the threshold values for algorithm switching between the available
+ methods.
+
+* The gcd algorithm could probably be improved with a divide-and-conquer
+ (DAC) approach. At least the bulk of the operations should be done with
+ single precision.
+
+* Fast output conversion of x to base B:
+ 1. Find n, such that (B^n > x).
+ 2. Set y to (x*2^m)/(B^n), where m large enough to make 2^n ~~ B^n
+ 3. Multiply the low half of y by B^(n/2), and recursively convert the
+ result. Truncate the low half of y and convert that recursively.
+ Complexity: O(M(n)log(n))+O(D(n))!
+
+* Extensions for floating-point arithmetic.
+
+* Improve special cases for division.
+
+ 1. When the divisor is just one word, normalization is not needed for
+ most CPUs, and can be done in the division loop for CPUs that need
+ normalization.
+
+ 2. Even when the result is going to be very small, (i.e. nsize-dsize is
+ small) normalization should also be done in the division loop.
+
+ To fix this, a new routine mpn_div_unnormalized is needed.
+
+* Never allocate temporary space for a source param that overlaps with a
+ destination param needing reallocation. Instead malloc a new block for
+ the destination (and free the source before returning to the caller).
+
+* When any of the source operands overlap with the destination, mult (and
+ other routines) slow down. This is so because the need of temporary
+ allocation (with alloca) and copying. If a new destination were
+ malloc'ed instead (and the overlapping source free'd before return) no
+ copying would be needed. Is GNU malloc quick enough to make this faster
+ even for reasonably small operands?
+
+Local Variables:
+mode: text
+fill-column: 75
+version-control: never
+End:
diff --git a/gnu/lib/libgmp/VERSION b/gnu/lib/libgmp/VERSION
new file mode 100644
index 0000000..bf76b46
--- /dev/null
+++ b/gnu/lib/libgmp/VERSION
@@ -0,0 +1 @@
+GNU MP version 1.3.2
diff --git a/gnu/lib/libgmp/_mpz_get_str.c b/gnu/lib/libgmp/_mpz_get_str.c
new file mode 100644
index 0000000..a83e690
--- /dev/null
+++ b/gnu/lib/libgmp/_mpz_get_str.c
@@ -0,0 +1,309 @@
+/* _mpz_get_str (string, base, mp_src) -- Convert the multiple precision
+ number MP_SRC to a string STRING of base BASE. If STRING is NULL
+ allocate space for the result. In any case, return a pointer to the
+ result. If STRING is not NULL, the caller must ensure enough space is
+ available to store the result.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+#define udiv_qrnndx(q, r, nh, nl, d, di) \
+ do { \
+ unsigned long int _q, _ql, _r; \
+ unsigned long int _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**32 too small. Compensate */\
+ if (_q < (nh)) \
+ { \
+ /* Got carry. Propagate it in the multiplication. */ \
+ umul_ppmm (_xh, _xl, (d), _q); \
+ _xh += (d); \
+ } \
+ else \
+ umul_ppmm (_xh, _xl, (d), _q); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ } \
+ } \
+ if (_r >= (d)) \
+ { \
+ _r -= (d); \
+ _q += 1; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+char *
+#ifdef __STDC__
+_mpz_get_str (char *str, int base, const MP_INT *m)
+#else
+_mpz_get_str (str, base, m)
+ char *str;
+ int base;
+ const MP_INT *m;
+#endif
+{
+ mp_ptr tp;
+ mp_size msize;
+ mp_limb big_base;
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+
+ int normalization_steps;
+#if UDIV_TIME > 2 * UMUL_TIME
+ mp_limb big_base_inverted;
+#endif
+#endif
+ unsigned int dig_per_u;
+ mp_size out_len;
+ char *s;
+ char *num_to_ascii;
+
+ if (base >= 0)
+ {
+ if (base == 0)
+ base = 10;
+ num_to_ascii = "0123456789abcdefghijklmnopqrstuvwxyz";
+ }
+ else
+ {
+ base = -base;
+ num_to_ascii = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ dig_per_u = __mp_bases[base].chars_per_limb;
+ out_len = mpz_sizeinbase (m, base) + 1;
+ big_base = __mp_bases[base].big_base;
+
+ msize = m->size;
+
+ if (str == NULL)
+ str = (char *) (*_mp_allocate_func) (out_len + (msize < 0));
+
+ if (msize < 0)
+ *str++ = '-';
+ s = str;
+
+ msize = ABS (msize);
+
+ /* Special case zero, as the code below doesn't handle it. */
+ if (msize == 0)
+ {
+ s[0] = '0';
+ s[1] = 0;
+ return str;
+ }
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* The base is a power of 2. Make conversion from most
+ significant side. */
+ mp_limb n1, n0;
+ int bits_per_digit = big_base;
+ int x;
+ int bit_pos;
+ int i;
+ unsigned mask = (1 << bits_per_digit) - 1;
+
+ tp = m->d;
+ n1 = tp[msize - 1];
+ count_leading_zeros (x, n1);
+
+ /* BIT_POS should be R when input ends in least sign. nibble,
+ R + bits_per_digit * n when input ends in n:th least significant
+ nibble. */
+
+ {
+ int bits;
+
+ bits = BITS_PER_MP_LIMB * msize - x;
+ x = bits % bits_per_digit;
+ if (x != 0)
+ bits += bits_per_digit - x;
+ bit_pos = bits - (msize - 1) * BITS_PER_MP_LIMB;
+ }
+
+ /* Fast loop for bit output. */
+ i = msize - 1;
+ for (;;)
+ {
+ bit_pos -= bits_per_digit;
+ while (bit_pos >= 0)
+ {
+ *s++ = num_to_ascii[(n1 >> bit_pos) & mask];
+ bit_pos -= bits_per_digit;
+ }
+ i--;
+ if (i < 0)
+ break;
+ n0 = (n1 << -bit_pos) & mask;
+ n1 = tp[i];
+ bit_pos += BITS_PER_MP_LIMB;
+ *s++ = num_to_ascii[n0 | (n1 >> bit_pos)];
+ }
+
+ *s = 0;
+ }
+ else
+ {
+ /* General case. The base is not a power of 2. Make conversion
+ from least significant end. */
+
+ /* If udiv_qrnnd only handles divisors with the most significant bit
+ set, prepare BIG_BASE for being a divisor by shifting it to the
+ left exactly enough to set the most significant bit. */
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ count_leading_zeros (normalization_steps, big_base);
+ big_base <<= normalization_steps;
+#if UDIV_TIME > 2 * UMUL_TIME
+ /* Get the fixed-point approximation to 1/BIG_BASE. */
+ big_base_inverted = __mp_bases[base].big_base_inverted;
+#endif
+#endif
+
+ out_len--; /* now not include terminating \0 */
+ s += out_len;
+
+ /* Allocate temporary space and move the multi prec number to
+ convert there, as we need to overwrite it below, while
+ computing the successive remainders. */
+ tp = (mp_ptr) alloca ((msize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (tp, m->d, msize);
+
+ while (msize != 0)
+ {
+ int i;
+ mp_limb n0, n1;
+
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ /* If we shifted BIG_BASE above, shift the dividend too, to get
+ the right quotient. We need to do this every loop,
+ as the intermediate quotients are OK, but the quotient from
+ one turn in the loop is going to be the dividend in the
+ next turn, and the dividend needs to be up-shifted. */
+ if (normalization_steps != 0)
+ {
+ n0 = mpn_lshift (tp, tp, msize, normalization_steps);
+
+ /* If the shifting gave a carry out limb, store it and
+ increase the length. */
+ if (n0 != 0)
+ {
+ tp[msize] = n0;
+ msize++;
+ }
+ }
+#endif
+
+ /* Divide the number at TP with BIG_BASE to get a quotient and a
+ remainder. The remainder is our new digit in base BIG_BASE. */
+ i = msize - 1;
+ n1 = tp[i];
+
+ if (n1 >= big_base)
+ n1 = 0;
+ else
+ {
+ msize--;
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = tp[i];
+#if UDIV_TIME > 2 * UMUL_TIME
+ udiv_qrnndx (tp[i], n1, n1, n0, big_base, big_base_inverted);
+#else
+ udiv_qrnnd (tp[i], n1, n1, n0, big_base);
+#endif
+ }
+
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ /* If we shifted above (at previous UDIV_NEEDS_NORMALIZATION tests)
+ the remainder will be up-shifted here. Compensate. */
+ n1 >>= normalization_steps;
+#endif
+
+ /* Convert N1 from BIG_BASE to a string of digits in BASE
+ using single precision operations. */
+ for (i = dig_per_u - 1; i >= 0; i--)
+ {
+ *--s = num_to_ascii[n1 % base];
+ n1 /= base;
+ /* Break from the loop as soon as we would only write zeros. */
+ if (n1 == 0 && msize == 0)
+ break;
+ }
+ }
+
+ /* There should be no leading zeros. */
+ if (*s == '0')
+ abort ();
+
+ if (s == str)
+ {
+ /* This should be the common case. */
+ s[out_len] = 0;
+ }
+ else if (s == str + 1)
+ {
+ /* The string became 1 digit shorter than its maximum. */
+ /* Need to copy it back one char pos. */
+ out_len--;
+#ifndef HAS_MEMMOVE
+ {
+ size_t i;
+
+ for (i = 0; i < out_len; i++)
+ str[i] = s[i];
+ }
+#else
+ memmove (str, s, out_len);
+#endif
+ str[out_len] = 0;
+ }
+ else
+ {
+ /* Hopefully never. */
+ abort ();
+ }
+ }
+
+ alloca (0);
+ /* Ugly, we incremented str for negative numbers. Fix that here. */
+ return str - (m->size < 0);
+}
diff --git a/gnu/lib/libgmp/_mpz_set_str.c b/gnu/lib/libgmp/_mpz_set_str.c
new file mode 100644
index 0000000..987f981
--- /dev/null
+++ b/gnu/lib/libgmp/_mpz_set_str.c
@@ -0,0 +1,258 @@
+/* _mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated
+ string STRING in base BASE to multiple precision integer in
+ MP_DEST. Allow white space in the string. If BASE == 0 determine
+ the base in the C standard way, i.e. 0xhh...h means base 16,
+ 0oo...o means base 8, otherwise assume base 10.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+enum char_type
+{
+ XX = -3,
+ SPC = -2,
+ EOF = -1
+};
+
+static signed char ascii_to_num[256] =
+{
+ EOF,XX, XX, XX, XX, XX, XX, XX, XX, SPC,SPC,XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ SPC,XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, XX, XX, XX, XX, XX, XX,
+ XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
+ XX, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX,
+ XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX, XX
+};
+
+int
+#ifdef __STDC__
+_mpz_set_str (MP_INT *x, const char *str, int base)
+#else
+_mpz_set_str (x, str, base)
+ MP_INT *x;
+ const char *str;
+ int base;
+#endif
+{
+ mp_ptr xp;
+ mp_size size;
+ mp_limb big_base;
+ int indigits_per_limb;
+ int negative = 0;
+ int inp_rawchar;
+ mp_limb inp_digit;
+ mp_limb res_digit;
+ size_t str_len;
+ mp_size i;
+
+ if (str[0] == '-')
+ {
+ negative = 1;
+ str++;
+ }
+
+ if (base == 0)
+ {
+ if (str[0] == '0')
+ {
+ if (str[1] == 'x' || str[1] == 'X')
+ base = 16;
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ big_base = __mp_bases[base].big_base;
+ indigits_per_limb = __mp_bases[base].chars_per_limb;
+
+ str_len = strlen (str);
+
+ size = str_len / indigits_per_limb + 1;
+ if (x->alloc < size)
+ _mpz_realloc (x, size);
+ xp = x->d;
+
+ size = 0;
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* The base is a power of 2. Read the input string from
+ least to most significant character/digit. */
+
+ const char *s;
+ int next_bitpos;
+ int bits_per_indigit = big_base;
+
+ /* Accept and ignore 0x or 0X before hexadecimal numbers. */
+ if (base == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ {
+ str += 2;
+ str_len -= 2;
+ }
+
+ res_digit = 0;
+ next_bitpos = 0;
+
+ for (s = str + str_len - 1; s >= str; s--)
+ {
+ inp_rawchar = *s;
+ inp_digit = ascii_to_num[inp_rawchar];
+
+ if (inp_digit >= base)
+ {
+ /* Was it white space? Just ignore it. */
+ if ((char) inp_digit == (char) SPC)
+ continue;
+
+ /* We found rubbish in the string. Return -1 to indicate
+ the error. */
+ return -1;
+ }
+
+ res_digit |= inp_digit << next_bitpos;
+ next_bitpos += bits_per_indigit;
+ if (next_bitpos >= BITS_PER_MP_LIMB)
+ {
+ xp[size] = res_digit;
+ size++;
+ next_bitpos -= BITS_PER_MP_LIMB;
+ res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
+ }
+ }
+
+ xp[size] = res_digit;
+ size++;
+ for (i = size - 1; i >= 0; i--)
+ {
+ if (xp[i] != 0)
+ break;
+ }
+ size = i + 1;
+ }
+ else
+ {
+ /* General case. The base is not a power of 2. */
+
+ mp_size i;
+ int j;
+ mp_limb cy;
+
+ for (;;)
+ {
+ res_digit = 0;
+ for (j = 0; j < indigits_per_limb; )
+ {
+ inp_rawchar = (unsigned char) *str++;
+ inp_digit = ascii_to_num[inp_rawchar];
+
+ /* Negative means that the character was not a proper digit. */
+ if (inp_digit >= base)
+ {
+ /* Was it white space? Just ignore it. */
+ if ((char) inp_digit == (char) SPC)
+ continue;
+
+ goto end_or_error;
+ }
+
+ res_digit = res_digit * base + inp_digit;
+
+ /* Increment the loop counter here, since it mustn't be
+ incremented when we do "continue" above. */
+ j++;
+ }
+
+ cy = res_digit;
+
+ /* Insert RES_DIGIT into the result multi prec integer. */
+ for (i = 0; i < size; i++)
+ {
+ mp_limb p1, p0;
+ umul_ppmm (p1, p0, big_base, xp[i]);
+ p0 += cy;
+ cy = p1 + (p0 < cy);
+ xp[i] = p0;
+ }
+ if (cy != 0)
+ {
+ xp[size] = cy;
+ size++;
+ }
+ }
+
+ end_or_error:
+ /* We probably have some digits in RES_DIGIT (J tells how many). */
+ if ((char) inp_digit != (char) EOF)
+ {
+ /* Error return. */
+ return -1;
+ }
+
+ /* J contains number of digits (in base BASE) remaining in
+ RES_DIGIT. */
+ if (j > 0)
+ {
+ big_base = 1;
+ do
+ {
+ big_base *= base;
+ j--;
+ }
+ while (j > 0);
+
+ cy = res_digit;
+
+ /* Insert ultimate RES_DIGIT into the result multi prec integer. */
+ for (i = 0; i < size; i++)
+ {
+ mp_limb p1, p0;
+ umul_ppmm (p1, p0, big_base, xp[i]);
+ p0 += cy;
+ cy = p1 + (p0 < cy);
+ xp[i] = p0;
+ }
+ if (cy != 0)
+ {
+ xp[size] = cy;
+ size++;
+ }
+ }
+ }
+
+ if (negative)
+ size = -size;
+ x->size = size;
+
+ return 0;
+}
diff --git a/gnu/lib/libgmp/alloca.c b/gnu/lib/libgmp/alloca.c
new file mode 100644
index 0000000..91d64bb
--- /dev/null
+++ b/gnu/lib/libgmp/alloca.c
@@ -0,0 +1,466 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* If compiling with GCC, this file's not needed. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+#ifdef emacs
+#define free xfree
+#endif
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#ifdef CRAY
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define NULL 0
+
+extern pointer (*_mp_allocate_func) ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = (*_mp_allocate_func) (sizeof (header) + size);
+ /* Address of header. */
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#ifdef CRAY
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
diff --git a/gnu/lib/libgmp/config.guess b/gnu/lib/libgmp/config.guess
new file mode 100755
index 0000000..afd200a
--- /dev/null
+++ b/gnu/lib/libgmp/config.guess
@@ -0,0 +1,592 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 1996 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 <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# 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).
+#
+
+# 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
+
+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
+ alpha:OSF1:[VX]*:*)
+ # After 1.2, OSF1 uses "V1.3" for uname -r.
+ # After 4.x, OSF1 uses "X4.x" for uname -r.
+ echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VX]//'`
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ # 1.2 uses "1.2" for uname -r.
+ echo alpha-dec-osf${UNAME_RELEASE}
+ 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:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ Pyramid*:OSx*:*:*)
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ sun4*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-unknown-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 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:4*:UMIPS)
+ echo mips-mips-riscos4sysv
+ exit 0 ;;
+ mips:*:5*:RISCos)
+ 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=`uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${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[34]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 <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} 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)
+ if /usr/sbin/lsattr -EHl proc0 | 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 NetBSD 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/[3478]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
+ 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ 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 <unistd.h>
+ 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-cc} 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 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ 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*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*C90:*:*:*)
+ echo c90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i[34]86:BSD/386:*:* | *: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 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo i386-unknown-cygwin32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ 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.
+ ld_help_string=`ld --help 2>&1`
+ if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
+ echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+ elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
+ echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+ elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
+ echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
+ elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
+ echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+ elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
+ echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+ elif test "${UNAME_MACHINE}" = "alpha" ; then
+ echo alpha-unknown-linux ; exit 0
+ else
+ # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
+ # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
+ test ! -d /usr/lib/ldscripts/. \
+ && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
+ # Determine whether the default compiler is a.out or elf
+ cat >dummy.c <<EOF
+main(argc, argv)
+int argc;
+char *argv[];
+{
+#ifdef __ELF__
+ printf ("%s-unknown-linux\n", argv[1]);
+#else
+ printf ("%s-unknown-linuxaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} 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[34]86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i[34]86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
+ elif /bin/uname -X 2>/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
+ echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-unknown-sysv32
+ fi
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-unknown-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 ;;
+ M680[234]0:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
+ uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3 && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m680[234]0:LynxOS:2.[23]*:*)
+ echo m68k-lynx-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i[34]86:LynxOS:2.[23]*:*)
+ echo i386-lynx-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.[23]*:*)
+ echo sparc-lynx-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.[23]*:*)
+ echo rs6000-lynx-lynxos${UNAME_RELEASE}
+ 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 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${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 <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#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 <sys/param.h>
+ 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`;
+ printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
+ 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-unknown-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-cc} 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/gnu/lib/libgmp/config.sub b/gnu/lib/libgmp/config.sub
new file mode 100755
index 0000000..997f9db
--- /dev/null
+++ b/gnu/lib/libgmp/config.sub
@@ -0,0 +1,1094 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 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.
+
+# 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
+# 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 (if any).
+basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+if [ $basic_machine != $1 ]
+then os=`echo $1 | sed 's/.*-/-/'`
+else os=; fi
+
+### 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 )
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL
+ os=
+ basic_machine=$1
+ ;;
+ -apple*) # CYGNUS LOCAL
+ os=
+ basic_machine=$1
+ ;;
+ -scout) # CYGNUS LOCAL
+ ;;
+ -wrs) # CYGNUS LOCAL
+ os=vxworks
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+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 | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | armeb \
+ | armel | pyramid \
+ | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
+ | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
+ | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
+ | pdp11 | mips64el | mips64orion | mips64orionel \
+ | sparc | sparc8 | supersparc | microsparc | ultrasparc)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m88110 | m680[012346]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
+ basic_machine=$basic_machine-unknown
+ ;;
+ mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith
+ basic_machine=$basic_machine-unknown
+ ;;
+ # 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.
+ vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
+ | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
+ | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
+ | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
+ | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
+ | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* \
+ | mips64-* | mipsel-* | mips64el-* | mips64orion-* \
+ | mips64orionel-* | sparc8-* | supersparc-* | microsparc-* | ultrasparc-*)
+ ;;
+ m88110-* | m680[012346]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL
+ ;;
+ mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd) # CYGNUS LOCAL
+ 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) # CYGNUS LOCAL
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k) # CYGNUS LOCAL
+ 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
+ ;;
+ amigados)
+ basic_machine=m68k-cbm
+ os=-amigados
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd) # CYGNUS LOCAL
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ arm | armel | armeb)
+ basic_machine=arm-arm
+ os=-aout
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ [ctj]90-cray)
+ 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 | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-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) # CYGNUS LOCAL
+ 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) # CYGNUS LOCAL
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms) # CYGNUS LOCAL
+ 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
+ ;;
+ w89k-*) # CYGNUS LOCAL
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ op50n-*) # CYGNUS LOCAL
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ op60c-*) # CYGNUS LOCAL
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ hppro) # CYGNUS LOCAL
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppaosf) # CYGNUS LOCAL
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[3456]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ os=-sysv32
+ ;;
+ i[3456]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ os=-sysv4
+ ;;
+ i[3456]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ os=-sysv
+ ;;
+ i[3456]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ os=-solaris2
+ ;;
+ i386mach) # CYGNUS LOCAL
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta) # CYGNUS LOCAL
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ i386-go32 | go32) # CYGNUS LOCAL
+ basic_machine=i386-unknown
+ os=-go32
+ ;;
+ 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
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor) # CYGNUS LOCAL
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos) # CYGNUS LOCAL
+ basic_machine=i386-unknown
+ os=-msdos
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown # CYGNUS LOCAL
+ os=-netbsd
+ ;;
+ 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) # CYGNUS LOCAL
+ 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
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ OSE68000 | ose68000) # CYGNUS LOCAL
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k) # CYGNUS LOCAL
+ 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)
+ basic_machine=i586-intel
+ ;;
+ pentiumpro | p6)
+ basic_machine=i686-intel
+ ;;
+ pentium-* | p5-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ k5)
+ # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+ basic_machine=i586-amd
+ ;;
+ nexgen)
+ # We don't have specific support for Nexgen yet, so just call it a Pentium
+ basic_machine=i586-nexgen
+ ;;
+ 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) # CYGNUS LOCAL
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200) # CYGNUS LOCAL
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs) # CYGNUS LOCAL
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sparcfrw) # CYGNUS LOCAL
+ basic_machine=sparcfrw-sun
+ os=-sunos4
+ ;;
+ sparcfrwcompat) # CYGNUS LOCAL
+ basic_machine=sparcfrwcompat-sun
+ os=-sunos4
+ ;;
+ sparclitefrw) # CYGNUS LOCAL
+ basic_machine=sparclitefrw-fujitsu
+ ;;
+ sparclitefrwcompat) # CYGNUS LOCAL
+ basic_machine=sparclitefrwcompat-fujitsu
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000) # CYGNUS LOCAL
+ basic_machine=m68k-tandem
+ ;;
+ stratus) # CYGNUS LOCAL
+ 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
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810) # CYGNUS LOCAL
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k) # CYGNUS LOCAL
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*) # CYGNUS LOCAL
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff) # CYGNUS LOCAL
+ 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) # CYGNUS LOCAL
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n) # CYGNUS LOCAL
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c) # CYGNUS LOCAL
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ basic_machine=mips-mips
+ ;;
+ 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)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw) # CYGNUS LOCAL
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw) # CYGNUS LOCAL
+ basic_machine=powerpc-apple
+ ;;
+ *)
+ 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
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -unixware* | svr4*)
+ os=-sysv4
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux|'`
+ ;;
+ # 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* | -lites* | -minix* | -genix* | -ultrix* | -irix* \
+ | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* \
+ | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
+ | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* | -lites* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi \
+ | -eabi* | -ieee*)
+ ;;
+ # CYGNUS LOCAL
+ -go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -proelf | -os9* \
+ | -macos* | -mpw* | -magic* | -pe* | -win32)
+ ;;
+ -mac*) # CYGNUS LOCAL
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd) # CYGNUS LOCAL
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ # 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*) # CYGNUS LOCAL
+ os=-ose
+ ;;
+ -es1800*) # CYGNUS LOCAL
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -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
+ ;;
+ 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) # CYGNUS LOCAL
+ os=-aout
+ ;;
+ mips*-cisco) # CYGNUS LOCAL
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec) # CYGNUS LOCAL
+ os=-proelf
+ ;;
+ *-winbond) # CYGNUS LOCAL
+ os=-proelf
+ ;;
+ *-oki) # CYGNUS LOCAL
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigados
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-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
+ ;;
+ *-rom68k) # CYGNUS LOCAL
+ os=-coff
+ ;;
+ *-*bug) # CYGNUS LOCAL
+ os=-coff
+ ;;
+ *-apple) # CYGNUS LOCAL
+ os=-macos
+ ;;
+ *)
+ 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
+ ;;
+ -bosx*) # CYGNUS LOCAL
+ vendor=bull
+ ;;
+ -lynxos*)
+ vendor=lynx
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxworks*)
+ vendor=wrs
+ ;;
+ -hms*) # CYGNUS LOCAL
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*) # CYGNUS LOCAL
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/gnu/lib/libgmp/config/mt-linux b/gnu/lib/libgmp/config/mt-linux
new file mode 100644
index 0000000..476d8b5
--- /dev/null
+++ b/gnu/lib/libgmp/config/mt-linux
@@ -0,0 +1 @@
+AR_FLAGS = qc
diff --git a/gnu/lib/libgmp/config/mt-m88110 b/gnu/lib/libgmp/config/mt-m88110
new file mode 100644
index 0000000..071f8fa
--- /dev/null
+++ b/gnu/lib/libgmp/config/mt-m88110
@@ -0,0 +1 @@
+XCFLAGS = -m88110
diff --git a/gnu/lib/libgmp/config/mt-sprc8-gcc b/gnu/lib/libgmp/config/mt-sprc8-gcc
new file mode 100644
index 0000000..bc706a9
--- /dev/null
+++ b/gnu/lib/libgmp/config/mt-sprc8-gcc
@@ -0,0 +1 @@
+XCFLAGS = -mv8
diff --git a/gnu/lib/libgmp/config/mt-supspc-gcc b/gnu/lib/libgmp/config/mt-supspc-gcc
new file mode 100644
index 0000000..92a0924
--- /dev/null
+++ b/gnu/lib/libgmp/config/mt-supspc-gcc
@@ -0,0 +1 @@
+XCFLAGS = -mv8 -DSUPERSPARC
diff --git a/gnu/lib/libgmp/configure b/gnu/lib/libgmp/configure
new file mode 100755
index 0000000..1554506
--- /dev/null
+++ b/gnu/lib/libgmp/configure
@@ -0,0 +1,1263 @@
+#!/bin/sh
+
+### WARNING: this file contains embedded tabs. Do not run untabify on this file.
+
+# Configuration script
+# Copyright (C) 1988, 90, 91, 92, 93, 94 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 file was originally written by K. Richard Pixley.
+
+#
+# Shell script to create proper links to machine-dependent files in
+# preparation for compilation.
+#
+# If configure succeeds, it leaves its status in config.status.
+# If configure fails after disturbing the status quo,
+# config.status is removed.
+#
+
+export PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh $0 $argv; kill $$)
+
+remove=rm
+hard_link=ln
+symbolic_link='ln -s'
+
+#for Test
+#remove="echo rm"
+#hard_link="echo ln"
+#symbolic_link="echo ln -s"
+
+# clear some things potentially inherited from environment.
+
+Makefile=Makefile
+Makefile_in=Makefile.in
+arguments=
+build_alias=
+cache_file=
+cache_file_option=
+configdirs=
+exec_prefix=
+exec_prefixoption=
+fatal=
+floating_point=default
+gas=default
+host_alias=NOHOST
+host_makefile_frag=
+moveifchange=
+norecursion=
+other_options=
+package_makefile_frag=
+prefix=/usr/local
+progname=
+program_prefix=
+program_prefixoption=
+program_suffix=
+program_suffixoption=
+program_transform_name=
+program_transform_nameoption=
+redirect=">/dev/null"
+removing=
+site=
+site_makefile_frag=
+site_option=
+srcdir=
+srctrigger=
+subdirs=
+target_alias=NOTARGET
+target_makefile_frag=
+undefs=NOUNDEFS
+version="$Revision: 1.218 (modified for gmp) $"
+x11=default
+
+### we might need to use some other shell than /bin/sh for running subshells
+#
+config_shell=${CONFIG_SHELL-/bin/sh}
+
+NO_EDIT="This file was generated automatically by configure. Do not edit."
+
+## this is a little touchy and won't always work, but...
+##
+## if the argv[0] starts with a slash then it is an absolute name that can (and
+## must) be used as is.
+##
+## otherwise, if argv[0] has no slash in it, we can assume that it is on the
+## path. Since PATH might include "." we also add `pwd` to the end of PATH.
+##
+
+progname=$0
+# if PWD already has a value, it is probably wrong.
+if [ -n "$PWD" ]; then PWD=`pwd`; fi
+
+case "${progname}" in
+/*) ;;
+*/*) ;;
+*)
+ PATH=$PATH:${PWD=`pwd`} ; export PATH
+ ;;
+esac
+
+# Loop over all args
+
+while :
+do
+
+# Break out if there are no more args
+ case $# in
+ 0)
+ break
+ ;;
+ esac
+
+# Get the first arg, and shuffle
+ option=$1
+ shift
+
+# Make all options have two hyphens
+ orig_option=$option # Save original for error messages
+ case $option in
+ --*) ;;
+ -*) option=-$option ;;
+ esac
+
+# Split out the argument for options that take them
+ case $option in
+ --*=*)
+ optarg=`echo $option | sed -e 's/^[^=]*=//'`
+ arguments="$arguments $option"
+ ;;
+# These options have mandatory values. Since we didn't find an = sign,
+# the value must be in the next argument
+ --bu* | --cache* | --ex* | --ho* | --pre* | --program-p* | --program-s* | --program-t* | --si* | --sr* | --ta* | --tm* | --x-* | --bi* | --sb* | --li* | --da* | --sy* | --sh* | --lo* | --in* | --ol* | --ma*)
+ optarg=$1
+ shift
+ arguments="$arguments $option=$optarg"
+ ;;
+ --v)
+ arguments="$arguments -v"
+ ;;
+ --*)
+ arguments="$arguments $option"
+ ;;
+ esac
+
+# Now, process the options
+ case $option in
+
+ --build* | --bu*)
+ case "$build_alias" in
+ "") build_alias=$optarg ;;
+ *) echo '***' Can only configure for one build machine at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --cache*)
+ cache_file=$optarg
+ ;;
+ --disable-*)
+ enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
+ eval $enableopt=no
+ disableoptions="$disableoptions $option"
+ ;;
+ --enable-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+
+ enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $enableopt="$optarg"
+ enableoptions="$enableoptions $option"
+ ;;
+ --exec-prefix* | --ex*)
+ exec_prefix=$optarg
+ exec_prefixoption="--exec-prefix=$optarg"
+ ;;
+ --gas | --g*)
+ gas=yes
+ ;;
+ --help | --he*)
+ fatal=yes
+ ;;
+ --host* | --ho*)
+ case $host_alias in
+ NOHOST) host_alias=$optarg ;;
+ *) echo '***' Can only configure for one host at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --nfp | --nf*)
+ floating_point=no
+ floating_pointoption="--nfp"
+ ;;
+ --norecursion | --no*)
+ norecursion=yes
+ ;;
+ --prefix* | --pre*)
+ prefix=$optarg
+ prefixoption="--prefix=$optarg"
+ ;;
+ --program-prefix* | --program-p*)
+ program_prefix=$optarg
+ program_prefixoption="--program-prefix=$optarg"
+ ;;
+ --program-suffix* | --program-s*)
+ program_suffix=$optarg
+ program_suffixoption="--program-suffix=$optarg"
+ ;;
+ --program-transform-name* | --program-t*)
+ # Double any backslashes or dollar signs in the argument
+ program_transform_name="${program_transform_name} -e `echo ${optarg} | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\\\$/$$/g'`"
+ program_transform_nameoption="${program_transform_nameoption} --program-transform-name='$optarg'"
+ ;;
+ --rm)
+ removing=--rm
+ ;;
+ --silent | --sil* | --quiet | --q*)
+ redirect=">/dev/null"
+ verbose=--silent
+ ;;
+ --site* | --sit*)
+ site=$optarg
+ site_option="--site=$optarg"
+ ;;
+ --srcdir*/ | --sr*/)
+ # Remove trailing slashes. Otherwise, when the file name gets
+ # bolted into an object file as debug info, it has two slashes
+ # in it. Ordinarily this is ok, but emacs takes double slash
+ # to mean "forget the first part".
+ srcdir=`echo $optarg | sed -e 's:/$::'`
+ ;;
+ --srcdir* | --sr*)
+ srcdir=$optarg
+ ;;
+ --target* | --ta*)
+ case $target_alias in
+ NOTARGET) target_alias=$optarg ;;
+ *) echo '***' Can only configure for one target at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ --tmpdir* | --tm*)
+ TMPDIR=$optarg
+ tmpdiroption="--tmpdir=$optarg"
+ ;;
+ --verbose | --v | --verb*)
+ redirect=
+ verbose=--verbose
+ ;;
+ --version | --V | --vers*)
+ echo "This is Cygnus Configure version" `echo ${version} | sed 's/[ $:]//g'`
+ exit 0
+ ;;
+ --with-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+
+ withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $withopt="$optarg"
+ withoptions="$withoptions $option"
+ ;;
+ --without-*)
+ withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'`
+ eval $withopt=no
+ withoutoptions="$withoutoptions $option"
+ ;;
+ --x) with_x=yes
+ withoptions="$withoptions --with-x"
+ ;;
+ --x-i* | --x-l*) other_options="$other_options $orig_option"
+ ;;
+ --bi* | --sb* | --li* | --da* | --sy* | --sh* | --lo* | --in* | --ol* | --ma*)
+ # These options were added to autoconf for emacs.
+ ;;
+ --*)
+ echo "configure: Unrecognized option: \"$orig_option\"; use --help for usage." >&2
+ exit 1
+ ;;
+ *)
+ case $undefs in
+ NOUNDEFS) undefs=$option ;;
+ *) echo '***' Can only configure for one host and one target at a time. 1>&2
+ fatal=yes
+ ;;
+ esac
+ ;;
+ esac
+done
+
+# process host and target
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET UNDEFS
+#
+# The rules are:
+# 1. You aren't allowed to specify --host, --target, and undefs at the
+# same time.
+# 2. Host defaults to undefs.
+# 3. If undefs is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target defaults to undefs.
+# 5. If undefs is not specified, then target defaults to host.
+
+case "${fatal}" in
+"")
+ # Make sure that host, target & undefs aren't all specified at the
+ # same time.
+ case $host_alias---$target_alias---$undefs in
+ NOHOST---*---* | *---NOTARGET---* | *---*---NOUNDEFS)
+ ;;
+ *) echo '***' Can only configure for one host and one target at a time. 1>&2
+ fatal=yes
+ break 2
+ ;;
+ esac
+
+ # Now, do defaulting for host.
+ case $host_alias in
+ NOHOST)
+ case $undefs in
+ NOUNDEFS)
+ # Neither --host option nor undefs were present.
+ # Call config.guess.
+ guesssys=`echo ${progname} | sed 's/configure$/config.guess/'`
+ if host_alias=`${guesssys}`
+ then
+ # If the string we are going to use for
+ # the target is a prefix of the string
+ # we just guessed for the host, then
+ # assume we are running native, and force
+ # the same string for both target and host.
+ case $target_alias in
+ NOTARGET) ;;
+ *)
+ if expr $host_alias : $target_alias >/dev/null
+ then
+ host_alias=$target_alias
+ fi
+ ;;
+ esac
+ echo "Configuring for a ${host_alias} host." 1>&2
+ arguments="--host=$host_alias $arguments"
+ else
+ echo 'Config.guess failed to determine the host type. You need to specify one.' 1>&2
+ fatal=yes
+ fi
+ ;;
+ *)
+ host_alias=$undefs
+ arguments="--host=$host_alias $arguments"
+ undefs=NOUNDEFS
+ ;;
+ esac
+ esac
+
+ # Do defaulting for target. If --target option isn't present, default
+ # to undefs. If undefs isn't present, default to host.
+ case $target_alias in
+ NOTARGET)
+ case $undefs in
+ NOUNDEFS)
+ target_alias=$host_alias
+ ;;
+ *)
+ target_alias=$undefs
+ arguments="--target=$target_alias $arguments"
+ ;;
+ esac
+ esac
+ ;;
+*) ;;
+esac
+
+if [ -n "${fatal}" -o "${host_alias}" = "help" ] ; then
+ exec 1>&2
+ echo Usage: configure [OPTIONS] [HOST]
+ echo
+ echo Options: [defaults in brackets]
+ echo ' --prefix=MYDIR install into MYDIR [/usr/local]'
+ echo ' --exec-prefix=MYDIR install host-dependent files into MYDIR [/usr/local]'
+ echo ' --help print this message [normal config]'
+ echo ' --build=BUILD configure for building on BUILD [BUILD=HOST]'
+ echo ' --host=HOST configure for HOST [determined via config.guess]'
+ echo ' --norecursion configure this directory only [recurse]'
+ echo ' --program-prefix=FOO prepend FOO to installed program names [""]'
+ echo ' --program-suffix=FOO append FOO to installed program names [""]'
+ echo ' --program-transform-name=P transform installed names by sed pattern P [""]'
+ echo ' --site=SITE configure with site-specific makefile for SITE'
+ echo ' --srcdir=DIR find the sources in DIR [. or ..]'
+ echo ' --target=TARGET configure for TARGET [TARGET=HOST]'
+ echo ' --tmpdir=TMPDIR create temporary files in TMPDIR [/tmp]'
+ echo ' --nfp configure for software floating point [hard float]'
+ echo ' --with-FOO, --with-FOO=BAR package FOO is available (parameter BAR)'
+ echo ' --without-FOO package FOO is NOT available'
+ echo ' --enable-FOO, --enable-FOO=BAR include feature FOO (parameter BAR)'
+ echo ' --disable-FOO do not include feature FOO'
+ echo
+ echo 'Where HOST and TARGET are something like "sparc-sunos", "mips-sgi-irix5", etc.'
+ echo
+ if [ -r config.status ] ; then
+ cat config.status
+ fi
+
+ exit 1
+fi
+
+configsub=`echo ${progname} | sed 's/configure$/config.sub/'`
+moveifchange=`echo ${progname} | sed 's/configure$/move-if-change/'`
+
+# this is a hack. sun4 must always be a valid host alias or this will fail.
+if ${configsub} sun4 >/dev/null 2>&1 ; then
+ true
+else
+ echo '***' cannot find config.sub. 1>&2
+ exit 1
+fi
+
+touch config.junk
+if ${moveifchange} config.junk config.trash ; then
+ true
+else
+ echo '***' cannot find move-if-change. 1>&2
+ exit 1
+fi
+rm -f config.junk config.trash
+
+case "${srcdir}" in
+"")
+ if [ -r configure.in ] ; then
+ srcdir=.
+ else
+ if [ -r ${progname}.in ] ; then
+ srcdir=`echo ${progname} | sed 's:/configure$::'`
+ else
+ echo '***' "Can't find configure.in. Try using --srcdir=some_dir" 1>&2
+ exit 1
+ fi
+ fi
+ ;;
+*)
+ # Set srcdir to "." if that's what it is.
+ # This is important for multilib support.
+ if [ ! -d ${srcdir} ] ; then
+ echo "Invalid source directory ${srcdir}" >&2
+ exit 1
+ fi
+ pwd=`pwd`
+ srcpwd=`cd ${srcdir} ; pwd`
+ if [ "${pwd}" = "${srcpwd}" ] ; then
+ srcdir=.
+ fi
+esac
+
+### warn about some conflicting configurations.
+
+case "${srcdir}" in
+".") ;;
+*)
+ if [ -f ${srcdir}/config.status ] ; then
+ echo '***' Cannot configure here in \"${PWD=`pwd`}\" when \"${srcdir}\" is currently configured. 1>&2
+ exit 1
+ fi
+esac
+
+# default exec_prefix
+case "${exec_prefixoption}" in
+"") exec_prefix="\$(prefix)" ;;
+*) ;;
+esac
+
+### break up ${srcdir}/configure.in.
+case "`grep '^# per\-host:' ${srcdir}/configure.in`" in
+"")
+ echo '***' ${srcdir}/configure.in has no \"per-host:\" line. 1>&2
+ # Check for a directory that's been converted to use autoconf since
+ # it was last configured.
+ if grep AC_OUTPUT ${srcdir}/configure.in >/dev/null ; then
+ echo '***' Hmm, looks like this directory has been autoconfiscated. 1>&2
+ if [ -r ${srcdir}/configure ] ; then
+ echo '***' Running the local configure script. 1>&2
+ case "${cache_file}" in
+ "") cache_file_option= ;;
+ *) cache_file_option="--cache-file=${cache_file}" ;;
+ esac
+ srcdiroption="--srcdir=${srcdir}"
+ case "${build_alias}" in
+ "") buildopt= ;;
+ *) buildopt="--build=${build_alias}" ;;
+ esac
+ eval exec ${config_shell} ${srcdir}/configure ${verbose} \
+ ${buildopt} --host=${host_alias} --target=${target_alias} \
+ ${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
+ ${srcdiroption} \
+ ${program_prefixoption} ${program_suffixoption} \
+ ${program_transform_nameoption} ${site_option} \
+ ${withoptions} ${withoutoptions} \
+ ${enableoptions} ${disableoptions} ${floating_pointoption} \
+ ${cache_file_option} ${removing} ${other_options} ${redirect}
+ else
+ echo '***' There is no configure script present though. 1>&2
+ fi
+ fi
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "`grep '^# per\-target:' ${srcdir}/configure.in`" in
+"")
+ echo '***' ${srcdir}/configure.in has no \"per-target:\" line. 1>&2
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "${TMPDIR}" in
+"") TMPDIR=/tmp ; export TMPDIR ;;
+*) ;;
+esac
+
+# keep this filename short for &%*%$*# 14 char file names
+tmpfile=${TMPDIR}/cONf$$
+# Note that under many versions of sh a trap handler for 0 will *override* any
+# exit status you explicitly specify! At this point, the only non-error exit
+# is at the end of the script; these actions are duplicated there, minus
+# the "exit 1". Don't use "exit 0" anywhere after this without resetting the
+# trap handler, or you'll lose.
+trap "rm -f Makefile.tem ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos; exit 1" 0 1 2 15
+
+# split ${srcdir}/configure.in into common, per-host, per-target,
+# and post-target parts. Post-target is optional.
+sed -e '/^# per\-host:/,$d' ${srcdir}/configure.in > ${tmpfile}.com
+sed -e '1,/^# per\-host:/d' -e '/^# per\-target:/,$d' ${srcdir}/configure.in > ${tmpfile}.hst
+if grep '^# post-target:' ${srcdir}/configure.in >/dev/null ; then
+ sed -e '1,/^# per\-target:/d' -e '/^# post\-target:/,$d' ${srcdir}/configure.in > ${tmpfile}.tgt
+ sed -e '1,/^# post\-target:/d' ${srcdir}/configure.in > ${tmpfile}.pos
+else
+ sed -e '1,/^# per\-target:/d' ${srcdir}/configure.in > ${tmpfile}.tgt
+ echo >${tmpfile}.pos
+fi
+
+### do common part of configure.in
+
+. ${tmpfile}.com
+
+# some sanity checks on configure.in
+case "${srctrigger}" in
+"")
+ echo '***' srctrigger not set in ${PWD=`pwd`}/configure.in. 1>&2
+ exit 1
+ ;;
+*) ;;
+esac
+
+case "${build_alias}" in
+"")
+ if result=`${config_shell} ${configsub} ${host_alias}` ; then
+ build_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+ build=${build_cpu}-${build_vendor}-${build_os}
+ build_alias=${host_alias}
+ fi
+ ;;
+*)
+ if result=`${config_shell} ${configsub} ${build_alias}` ; then
+ buildopt="--build=${build_alias}"
+ build_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
+ build_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
+ build_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+ build=${build_cpu}-${build_vendor}-${build_os}
+ else
+ echo "Unrecognized build system name ${build_alias}." 1>&2
+ exit 1
+ fi
+ ;;
+esac
+
+if result=`${config_shell} ${configsub} ${host_alias}` ; then
+ true
+else
+ echo "Unrecognized host system name ${host_alias}." 1>&2
+ exit 1
+fi
+host_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
+host_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
+host_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+host=${host_cpu}-${host_vendor}-${host_os}
+
+. ${tmpfile}.hst
+
+if result=`${config_shell} ${configsub} ${target_alias}` ; then
+ true
+else
+ echo "Unrecognized target system name ${target_alias}." 1>&2
+ exit 1
+fi
+target_cpu=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
+target_vendor=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
+target_os=`echo $result | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+target=${target_cpu}-${target_vendor}-${target_os}
+
+. ${tmpfile}.tgt
+
+# Find the source files, if location was not specified.
+case "${srcdir}" in
+"")
+ srcdirdefaulted=1
+ srcdir=.
+ if [ ! -r ${srctrigger} ] ; then
+ srcdir=..
+ fi
+ ;;
+*) ;;
+esac
+
+if [ ! -r ${srcdir}/${srctrigger} ] ; then
+ case "${srcdirdefaulted}" in
+ "") echo '***' "${progname}: Can't find ${srcname} sources in ${PWD=`pwd`}/${srcdir}" 1>&2 ;;
+ *) echo '***' "${progname}: Can't find ${srcname} sources in ${PWD=`pwd`}/. or ${PWD=`pwd`}/.." 1>&2 ;;
+ esac
+
+ echo '***' \(At least ${srctrigger} is missing.\) 1>&2
+ exit 1
+fi
+
+# Some systems (e.g., one of the i386-aix systems the gas testers are
+# using) don't handle "\$" correctly, so don't use it here.
+tooldir='$(exec_prefix)'/${target_alias}
+
+if [ "${host_alias}" != "${target_alias}" ] ; then
+ if [ "${program_prefixoption}" = "" ] ; then
+ if [ "${program_suffixoption}" = "" ] ; then
+ if [ "${program_transform_nameoption}" = "" ] ; then
+ program_prefix=${target_alias}- ;
+ fi
+ fi
+ fi
+fi
+
+# Merge program_prefix and program_suffix onto program_transform_name.
+# (program_suffix used to use $, but it's hard to preserve $ through both
+# make and sh.)
+if [ "${program_suffix}" != "" ] ; then
+ program_transform_name="-e s,\\\\(.*\\\\),\\\\1${program_suffix}, ${program_transform_name}"
+fi
+
+if [ "${program_prefix}" != "" ] ; then
+ program_transform_name="-e s,^,${program_prefix}, ${program_transform_name}"
+fi
+
+# If CC and CXX are not set in the environment, and the Makefile
+# exists, try to extract them from it. This is to handle running
+# ./config.status by hand.
+if [ -z "${CC}" -a -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+/\\$/ b loop
+s/\\\n//g
+/^CC[ ]*=/ s/CC[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CC=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ -z "${CXX}" -a -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+/\\$/ b loop
+s/\\\n//g
+/^CXX[ ]*=/ s/CXX[ ]*=[ ]*\(.*\)/\1/p' < Makefile > Makefile.cc
+ CXX=`tail -1 Makefile.cc`
+ rm -f Makefile.cc
+fi
+
+if [ "${build}" != "${host}" ]; then
+ # If we are doing a Canadian Cross, in which the host and build systems
+ # are not the same, we set reasonable default values for the tools.
+
+ tools="AR AR_FOR_TARGET AS AS_FOR_TARGET BISON CC_FOR_BUILD"
+ tools="${tools} CC_FOR_TARGET CXX_FOR_TARGET"
+ tools="${tools} DLLTOOL DLLTOOL_FOR_TARGET HOST_PREFIX"
+ tools="${tools} HOST_PREFIX_1 LD LD_FOR_TARGET LEX MAKEINFO NM"
+ tools="${tools} NM_FOR_TARGET RANLIB RANLIB_FOR_TARGET"
+
+ for var in ${tools}; do
+ if [ -z "`eval 'echo $'"${var}"`" -a -r Makefile ]; then
+ sed -n -e ':loop
+/\\$/ N
+/\\$/ b loop
+s/\\\n//g
+/^'"${var}"'[ ]*=/ s/'"${var}"'[ ]*=[ ]*\(.*\)/\1/p' \
+ < Makefile > Makefile.v
+ t=`tail -1 Makefile.v`
+ if [ -n "${t}" ]; then
+ eval "${var}='${t}'"
+ fi
+ rm -f Makefile.v
+ fi
+ done
+
+ AR=${AR-${host_alias}-ar}
+ AR_FOR_TARGET=${AR_FOR_TARGET-${target_alias}-ar}
+ AS=${AS-${host_alias}-as}
+ AS_FOR_TARGET=${AS_FOR_TARGET-${target_alias}-as}
+ CC=${CC-${host_alias}-gcc}
+ CXX=${CXX-${host_alias}-gcc}
+ CC_FOR_BUILD=${CC_FOR_BUILD-gcc}
+ CC_FOR_TARGET=${CC_FOR_TARGET-${target_alias}-gcc}
+ CXX_FOR_TARGET=${CXX_FOR_TARGET-${target_alias}-gcc}
+ DLLTOOL=${DLLTOOL-${host_alias}-dlltool}
+ DLLTOOL_FOR_TARGET=${DLLTOOL_FOR_TARGET-${target_alias}-dlltool}
+ HOST_PREFIX=${build_alias}-
+ HOST_PREFIX_1=${build_alias}-
+ LD=${LD-${host_alias}-ld}
+ LD_FOR_TARGET=${LD_FOR_TARGET-${target_alias}-ld}
+ MAKEINFO=${MAKEINFO-makeinfo}
+ NM=${NM-${host_alias}-nm}
+ NM_FOR_TARGET=${NM_FOR_TARGET-${target_alias}-nm}
+ RANLIB=${RANLIB-${host_alias}-ranlib}
+ RANLIB_FOR_TARGET=${RANLIB_FOR_TARGET-${target_alias}-ranlib}
+
+ if [ -z "${BISON}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/byacc; then
+ BISON=byacc
+ break
+ fi
+ if test -f $dir/bison; then
+ BISON=bison
+ break
+ fi
+ if test -f $dir/yacc; then
+ BISON=yacc
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ BISON=${BISON-bison}
+ fi
+
+ if [ -z "${LEX}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/flex; then
+ LEX=flex
+ break
+ fi
+ if test -f $dir/lex; then
+ LEX=lex
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ LEX=${LEX-flex}
+ fi
+
+ # Export variables which autoconf might try to set.
+ export AS
+ export AR
+ export CC_FOR_BUILD
+ export DLLTOOL
+ export LD
+ export NM
+ export RANLIB
+else
+ # If CC is still not set, try to get gcc.
+ if [ x$with_gcc != xno -a -z "${CC}" ]; then
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc -O2"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ CC=${CC-cc}
+ fi
+
+ CXX=${CXX-"gcc"}
+fi
+
+export CC
+export CXX
+
+case "$host" in
+ *go32*)
+ enable_gdbtk=no ;;
+esac
+
+# Determine whether gdb needs tk/tcl or not.
+if [ "$enable_gdbtk" != "no" ]; then
+ GDB_TK="all-tcl all-tk"
+else
+ GDB_TK=""
+fi
+
+for subdir in . ${subdirs} ; do
+
+ # ${subdir} is relative path from . to the directory we're currently
+ # configuring.
+ # ${invsubdir} is inverse of ${subdir), *with* trailing /, if needed.
+ invsubdir=`echo ${subdir}/ | sed -e 's|\./||g' -e 's|[^/]*/|../|g'`
+
+ ### figure out what to do with srcdir
+ case "${srcdir}" in
+ ".") # no -srcdir option. We're building in place.
+ makesrcdir=. ;;
+ /*) # absolute path
+ makesrcdir=`echo ${srcdir}/${subdir} | sed -e 's|/\.$||'`
+ ;;
+ *) # otherwise relative
+ case "${subdir}" in
+ .) makesrcdir=${srcdir} ;;
+ *) makesrcdir=${invsubdir}${srcdir}/${subdir} ;;
+ esac
+ ;;
+ esac
+
+ if [ "${subdir}/" != "./" ] ; then
+ Makefile=${subdir}/Makefile
+ fi
+
+ if [ ! -d ${subdir} ] ; then
+ if mkdir ${subdir} ; then
+ true
+ else
+ echo '***' "${progname}: could not make ${PWD=`pwd`}/${subdir}" 1>&2
+ exit 1
+ fi
+ fi
+
+ case "${removing}" in
+ "")
+ case "${subdir}" in
+ .) ;;
+ *) eval echo Building in ${subdir} ${redirect} ;;
+ esac
+
+ # FIXME Should this be done recursively ??? (Useful for e.g. gdbtest)
+ # Set up the list of links to be made.
+ # ${links} is the list of link names, and ${files} is the list of names to link to.
+
+ # Make the links.
+ configlinks="${links}"
+ if [ -r ${subdir}/config.status ] ; then
+ mv -f ${subdir}/config.status ${subdir}/config.back
+ fi
+ while [ -n "${files}" ] ; do
+ # set file to car of files, files to cdr of files
+ set ${files}; file=$1; shift; files=$*
+ set ${links}; link=$1; shift; links=$*
+
+ if [ ! -r ${srcdir}/${file} ] ; then
+ echo '***' "${progname}: cannot create a link \"${link}\"," 1>&2
+ echo '***' "since the file \"${srcdir}/${file}\" does not exist." 1>&2
+ exit 1
+ fi
+
+ ${remove} -f ${link}
+ # Make a symlink if possible, otherwise try a hard link
+ if ${symbolic_link} ${srcdir}/${file} ${link} >/dev/null 2>&1 ; then
+ true
+ else
+ # We need to re-remove the file because Lynx leaves a
+ # very strange directory there when it fails an NFS symlink.
+ ${remove} -r -f ${link}
+ ${hard_link} ${srcdir}/${file} ${link}
+ fi
+ if [ ! -r ${link} ] ; then
+ echo '***' "${progname}: unable to link \"${link}\" to \"${srcdir}/${file}\"." 1>&2
+ exit 1
+ fi
+
+ echo "Linked \"${link}\" to \"${srcdir}/${file}\"."
+ done
+
+ # Create a .gdbinit file which runs the one in srcdir
+ # and tells GDB to look there for source files.
+
+ if [ -r ${srcdir}/${subdir}/.gdbinit ] ; then
+ case ${srcdir} in
+ .) ;;
+ *) cat > ${subdir}/.gdbinit <<EOF
+# ${NO_EDIT}
+dir ${makesrcdir}
+dir .
+source ${makesrcdir}/.gdbinit
+EOF
+ ;;
+ esac
+ fi
+
+ # Install a makefile, and make it set VPATH
+ # if necessary so that the sources are found.
+ # Also change its value of srcdir.
+ # NOTE: Makefile generation constitutes the majority of the time in configure. Hence, this section has
+ # been somewhat optimized and is perhaps a bit twisty.
+
+ # code is order so as to try to sed the smallest input files we know.
+
+ # the four makefile fragments MUST end up in the resulting Makefile in this order:
+ # package, target, host, and site. so do these separately because I don't trust the
+ # order of sed -e expressions.
+
+ if [ -f ${srcdir}/${subdir}/${Makefile_in} ] ; then
+
+ # Conditionalize for this site from "Makefile.in" (or whatever it's called) into Makefile.tem
+ rm -f ${subdir}/Makefile.tem
+ case "${site}" in
+ "") cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem ;;
+ *)
+ site_makefile_frag=${srcdir}/config/ms-${site}
+
+ if [ -f ${site_makefile_frag} ] ; then
+ sed -e "/^####/ r ${site_makefile_frag}" ${srcdir}/${subdir}/${Makefile_in} \
+ > ${subdir}/Makefile.tem
+ else
+ cp ${srcdir}/${subdir}/${Makefile_in} ${subdir}/Makefile.tem
+ site_makefile_frag=
+ fi
+ ;;
+ esac
+ # working copy now in ${subdir}/Makefile.tem
+
+ # Conditionalize the makefile for this host.
+ rm -f ${Makefile}
+ case "${host_makefile_frag}" in
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ *)
+ if [ ! -f ${host_makefile_frag} ] ; then
+ host_makefile_frag=${srcdir}/${host_makefile_frag}
+ fi
+ if [ -f ${host_makefile_frag} ] ; then
+ sed -e "/^####/ r ${host_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
+ else
+ echo '***' Expected host makefile fragment \"${host_makefile_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ mv ${subdir}/Makefile.tem ${Makefile}
+ fi
+ esac
+ # working copy now in ${Makefile}
+
+ # Conditionalize the makefile for this target.
+ rm -f ${subdir}/Makefile.tem
+ case "${target_makefile_frag}" in
+ "") mv ${Makefile} ${subdir}/Makefile.tem ;;
+ *)
+ if [ ! -f ${target_makefile_frag} ] ; then
+ target_makefile_frag=${srcdir}/${target_makefile_frag}
+ fi
+ if [ -f ${target_makefile_frag} ] ; then
+ sed -e "/^####/ r ${target_makefile_frag}" ${Makefile} > ${subdir}/Makefile.tem
+ else
+ mv ${Makefile} ${subdir}/Makefile.tem
+ target_makefile_frag=
+ fi
+ ;;
+ esac
+ # real copy now in ${subdir}/Makefile.tem
+
+ # Conditionalize the makefile for this package.
+ rm -f ${Makefile}
+ case "${package_makefile_frag}" in
+ "") mv ${subdir}/Makefile.tem ${Makefile} ;;
+ *)
+ if [ ! -f ${package_makefile_frag} ] ; then
+ package_makefile_frag=${srcdir}/${package_makefile_frag}
+ fi
+ if [ -f ${package_makefile_frag} ] ; then
+ sed -e "/^####/ r ${package_makefile_frag}" ${subdir}/Makefile.tem > ${Makefile}
+ rm -f ${subdir}/Makefile.tem
+ else
+ echo '***' Expected package makefile fragment \"${package_makefile_frag}\" 1>&2
+ echo '***' is missing in ${PWD=`pwd`}. 1>&2
+ mv ${subdir}/Makefile.tem ${Makefile}
+ fi
+ esac
+ # working copy now in ${Makefile}
+
+ mv ${Makefile} ${subdir}/Makefile.tem
+
+ # real copy now in ${subdir}/Makefile.tem
+
+ # prepend warning about editting, and a bunch of variables.
+ rm -f ${Makefile}
+ cat > ${Makefile} <<EOF
+# ${NO_EDIT}
+VPATH = ${makesrcdir}
+links = ${configlinks}
+host_alias = ${host_alias}
+host_cpu = ${host_cpu}
+host_vendor = ${host_vendor}
+host_os = ${host_os}
+host_canonical = ${host_cpu}-${host_vendor}-${host_os}
+target_alias = ${target_alias}
+target_cpu = ${target_cpu}
+target_vendor = ${target_vendor}
+target_os = ${target_os}
+target_canonical = ${target_cpu}-${target_vendor}-${target_os}
+EOF
+ case "${build}" in
+ "") ;;
+ *) cat >> ${Makefile} << EOF
+build_alias = ${build_alias}
+build_cpu = ${build_cpu}
+build_vendor = ${build_vendor}
+build_os = ${build_os}
+build_canonical = ${build_cpu}-${build_vendor}-${build_os}
+EOF
+ esac
+
+ case "${package_makefile_frag}" in
+ "") ;;
+ /*) echo package_makefile_frag = ${package_makefile_frag} >>${Makefile} ;;
+ *) echo package_makefile_frag = ${invsubdir}${package_makefile_frag} >>${Makefile} ;;
+ esac
+
+ case "${target_makefile_frag}" in
+ "") ;;
+ /*) echo target_makefile_frag = ${target_makefile_frag} >>${Makefile} ;;
+ *) echo target_makefile_frag = ${invsubdir}${target_makefile_frag} >>${Makefile} ;;
+ esac
+
+ case "${host_makefile_frag}" in
+ "") ;;
+ /*) echo host_makefile_frag = ${host_makefile_frag} >>${Makefile} ;;
+ *) echo host_makefile_frag = ${invsubdir}${host_makefile_frag} >>${Makefile} ;;
+ esac
+
+ if [ "${site_makefile_frag}" != "" ] ; then
+ echo site_makefile_frag = ${invsubdir}${site_makefile_frag} >>${Makefile}
+ fi
+
+ # reset prefix, exec_prefix, srcdir, SUBDIRS, NONSUBDIRS,
+ # remove any form feeds.
+ if [ -z "${subdirs}" ]; then
+ rm -f ${subdir}/Makefile.tem2
+ sed -e "s:^SUBDIRS[ ]*=.*$:SUBDIRS = ${configdirs}:" \
+ -e "s:^NONSUBDIRS[ ]*=.*$:NONSUBDIRS = ${noconfigdirs}:" \
+ ${subdir}/Makefile.tem > ${subdir}/Makefile.tem2
+ rm -f ${subdir}/Makefile.tem
+ mv ${subdir}/Makefile.tem2 ${subdir}/Makefile.tem
+ fi
+ sed -e "s:^prefix[ ]*=.*$:prefix = ${prefix}:" \
+ -e "s:^exec_prefix[ ]*=.*$:exec_prefix = ${exec_prefix}:" \
+ -e "/^CC[ ]*=/{
+ :loop1
+ /\\\\$/ N
+ /\\\\$/ b loop1
+ s/\\\\\\n//g
+ s%^CC[ ]*=.*$%CC = ${CC}%
+ }" \
+ -e "/^CXX[ ]*=/{
+ :loop2
+ /\\\\$/ N
+ /\\\\$/ b loop2
+ s/\\\\\\n//g
+ s%^CXX[ ]*=.*$%CXX = ${CXX}%
+ }" \
+ -e "s:^SHELL[ ]*=.*$:SHELL = ${config_shell}:" \
+ -e "s:^GDB_TK[ ]*=.*$:GDB_TK = ${GDB_TK}:" \
+ -e "s:^srcdir[ ]*=.*$:srcdir = ${makesrcdir}:" \
+ -e "s/ //" \
+ -e "s:^program_prefix[ ]*=.*$:program_prefix = ${program_prefix}:" \
+ -e "s:^program_suffix[ ]*=.*$:program_suffix = ${program_suffix}:" \
+ -e "s:^program_transform_name[ ]*=.*$:program_transform_name = ${program_transform_name}:" \
+ -e "s:^tooldir[ ]*=.*$:tooldir = ${tooldir}:" \
+ ${subdir}/Makefile.tem >> ${Makefile}
+
+ # If this is a Canadian Cross, preset the values of many more
+ # tools.
+ if [ "${build}" != "${host}" ]; then
+ for var in ${tools}; do
+ val=`eval 'echo $'"${var}"`
+ sed -e "/^${var}[ ]*=/{
+ :loop1
+ /\\\\$/ N
+ /\\\\$/ b loop1
+ s/\\\\\\n//g
+ s%^${var}[ ]*=.*$%${var} = ${val}%
+ }" ${Makefile} > ${Makefile}.tem
+ mv -f ${Makefile}.tem ${Makefile}
+ done
+ fi
+
+ # final copy now in ${Makefile}
+
+ else
+ echo "No Makefile.in found in ${srcdir}/${subdir}, unable to configure" 1>&2
+ fi
+
+ rm -f ${subdir}/Makefile.tem
+
+ case "${host_makefile_frag}" in
+ "") using= ;;
+ *) using="and \"${host_makefile_frag}\"" ;;
+ esac
+
+ case "${target_makefile_frag}" in
+ "") ;;
+ *) using="${using} and \"${target_makefile_frag}\"" ;;
+ esac
+
+ case "${site_makefile_frag}" in
+ "") ;;
+ *) using="${using} and \"${site_makefile_frag}\"" ;;
+ esac
+
+ newusing=`echo "${using}" | sed 's/and/using/'`
+ using=${newusing}
+ echo "Created \"${Makefile}\" in" ${PWD=`pwd`} ${using}
+
+ . ${tmpfile}.pos
+
+ # describe the chosen configuration in config.status.
+ # Make that file a shellscript which will reestablish
+ # the same configuration. Used in Makefiles to rebuild
+ # Makefiles.
+
+ case "${norecursion}" in
+ "") arguments="${arguments} --norecursion" ;;
+ *) ;;
+ esac
+
+ if [ ${subdir} = . ] ; then
+ echo "#!/bin/sh
+# ${NO_EDIT}
+# This directory was configured as follows:
+${progname}" ${arguments} "
+# ${using}" > ${subdir}/config.new
+ else
+ echo "#!/bin/sh
+# ${NO_EDIT}
+# This directory was configured as follows:
+cd ${invsubdir}
+${progname}" ${arguments} "
+# ${using}" > ${subdir}/config.new
+ fi
+ chmod a+x ${subdir}/config.new
+ if [ -r ${subdir}/config.back ] ; then
+ mv -f ${subdir}/config.back ${subdir}/config.status
+ fi
+ ${moveifchange} ${subdir}/config.new ${subdir}/config.status
+ ;;
+
+ *) rm -f ${Makefile} ${subdir}/config.status ${links} ;;
+ esac
+done
+
+# If there are subdirectories, then recur.
+if [ -z "${norecursion}" -a -n "${configdirs}" ] ; then
+ for configdir in ${configdirs} ; do
+
+ if [ -d ${srcdir}/${configdir} ] ; then
+ eval echo Configuring ${configdir}... ${redirect}
+ case "${srcdir}" in
+ ".") ;;
+ *)
+ if [ ! -d ./${configdir} ] ; then
+ if mkdir ./${configdir} ; then
+ true
+ else
+ echo '***' "${progname}: could not make ${PWD=`pwd`}/${configdir}" 1>&2
+ exit 1
+ fi
+ fi
+ ;;
+ esac
+
+ POPDIR=${PWD=`pwd`}
+ cd ${configdir}
+
+### figure out what to do with srcdir
+ case "${srcdir}" in
+ ".") newsrcdir=${srcdir} ;; # no -srcdir option. We're building in place.
+ /*) # absolute path
+ newsrcdir=${srcdir}/${configdir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ *) # otherwise relative
+ newsrcdir=../${srcdir}/${configdir}
+ srcdiroption="--srcdir=${newsrcdir}"
+ ;;
+ esac
+
+ # Handle --cache-file=../XXX
+ case "${cache_file}" in
+ "") # empty
+ ;;
+ /*) # absolute path
+ cache_file_option="--cache-file=${cache_file}"
+ ;;
+ *) # relative path
+ cache_file_option="--cache-file=../${cache_file}"
+ ;;
+ esac
+
+### check for guested configure, otherwise fix possibly relative progname
+ if [ -f ${newsrcdir}/configure ] ; then
+ recprog=${newsrcdir}/configure
+ elif [ -f ${newsrcdir}/configure.in ] ; then
+ case "${progname}" in
+ /*) recprog=${progname} ;;
+ *) recprog=../${progname} ;;
+ esac
+ else
+ eval echo No configuration information in ${configdir} ${redirect}
+ recprog=
+ fi
+
+### The recursion line is here.
+ if [ ! -z "${recprog}" ] ; then
+ if eval ${config_shell} ${recprog} ${verbose} ${buildopt} --host=${host_alias} --target=${target_alias} \
+ ${prefixoption} ${tmpdiroption} ${exec_prefixoption} \
+ ${srcdiroption} ${program_prefixoption} ${program_suffixoption} ${program_transform_nameoption} ${site_option} ${withoptions} ${withoutoptions} ${enableoptions} ${disableoptions} ${floating_pointoption} ${cache_file_option} ${removing} ${other_options} ${redirect} ; then
+ true
+ else
+ echo Configure in `pwd` failed, exiting. 1>&2
+ exit 1
+ fi
+ fi
+
+ cd ${POPDIR}
+ fi
+ done
+fi
+
+# Perform the same cleanup as the trap handler, minus the "exit 1" of course,
+# and reset the trap handler.
+rm -f ${tmpfile}.com ${tmpfile}.tgt ${tmpfile}.hst ${tmpfile}.pos
+trap 0
+
+exit 0
+
+#
+# Local Variables:
+# fill-column: 131
+# End:
+#
+
+# end of configure
diff --git a/gnu/lib/libgmp/configure.in b/gnu/lib/libgmp/configure.in
new file mode 100644
index 0000000..42192b5
--- /dev/null
+++ b/gnu/lib/libgmp/configure.in
@@ -0,0 +1,35 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs="mpn mpz mpf mpq mpbsd"
+srctrigger=gmp-impl.h
+srcname="GNU Multi-Precision library"
+
+# per-host:
+
+# per-target:
+
+case "${target}" in
+ sparc8* | microsparc*)
+ if [ x$with_gcc != xno ]
+ then
+ target_makefile_frag=config/mt-sprc8-gcc
+ fi
+ ;;
+ supersparc*)
+ if [ x$with_gcc != xno ]
+ then
+ target_makefile_frag=config/mt-supspc-gcc
+ fi
+ ;;
+ m888110*)
+ if [ x$with_gcc != xno ]
+ then
+ target_makefile_frag=config/mt-m88110
+ fi
+ ;;
+ *-*-linux*)
+ target_makefile_frag=config/mt-linux ;;
+
+esac
diff --git a/gnu/lib/libgmp/cre-conv-tab.c b/gnu/lib/libgmp/cre-conv-tab.c
new file mode 100644
index 0000000..d5d1bea
--- /dev/null
+++ b/gnu/lib/libgmp/cre-conv-tab.c
@@ -0,0 +1,140 @@
+/* cre-conv-tab.c -- Create conversion table in a wordsize-dependent way.
+
+ $Id$
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <math.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static unsigned long int
+upow (unsigned long int b, unsigned int e)
+{
+ unsigned long int y = 1;
+
+ while (e != 0)
+ {
+ while ((e & 1) == 0)
+ {
+ b = b * b;
+ e >>= 1;
+ }
+ y = y * b;
+ e -= 1;
+ }
+
+ return y;
+}
+
+unsigned int
+ulog2 (unsigned long int x)
+{
+ unsigned int i;
+ for (i = 0; x != 0; i++)
+ x >>= 1;
+ return i;
+}
+
+void
+main (void)
+{
+ int i;
+ unsigned long idig;
+ unsigned long big_base, big_base_inverted;
+ double fdig;
+ int dummy;
+ int normalization_steps;
+
+ unsigned long int max_uli;
+ int bits_uli;
+
+ max_uli = 1;
+ for (i = 1; ; i++)
+ {
+ if ((max_uli << 1) == 0)
+ break;
+ max_uli <<= 1;
+ }
+ bits_uli = i;
+
+ puts ("/* __mp_bases -- Structure for conversion between internal binary");
+ puts (" format and strings in base 2..36. The fields are explained in");
+ puts (" gmp-impl.h.");
+ puts ("");
+ puts (" ***** THIS FILE WAS CREATED BY A PROGRAM. DON'T EDIT IT! *****");
+ puts ("");
+ puts ("Copyright (C) 1991 Free Software Foundation, Inc.");
+ puts ("");
+ puts ("This file is part of the GNU MP Library.");
+ puts ("");
+ puts ("The GNU MP Library is free software; you can redistribute it and/or");
+ puts ("modify it under the terms of the GNU General Public License as");
+ puts ("published by the Free Software Foundation; either version 2, or");
+ puts ("(at your option) any later version.");
+ puts ("");
+ puts ("The GNU MP Library is distributed in the hope that it will be");
+ puts ("useful, but WITHOUT ANY WARRANTY; without even the implied warranty");
+ puts ("of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
+ puts ("GNU General Public License for more details.");
+ puts ("");
+ puts ("You should have received a copy of the GNU General Public License");
+ puts ("along with the GNU MP Library; see the file COPYING. If not, write");
+ puts ("to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,");
+ puts ("USA. */");
+ puts ("");
+ puts ("#include \"gmp.h\"");
+ puts ("#include \"gmp-impl.h\"");
+ puts ("");
+
+ puts ("const struct bases __mp_bases[37] =\n{");
+ puts (" /* 0 */ {0, 0, 0, 0.0},");
+ puts (" /* 1 */ {0, 0, 0, 0.0},");
+ for (i = 2; i <= 36; i++)
+ {
+ /* The weird expression here is because many /bin/cc compilers
+ generate incorrect code for conversions from large unsigned
+ integers to double. */
+ fdig = log(2.0)/log((double) i);
+ idig = floor(bits_uli * fdig);
+ if ((i & (i - 1)) == 0)
+ {
+ big_base = ulog2 (i) - 1;
+ big_base_inverted = 0;
+ }
+ else
+ {
+ big_base = upow (i, idig);
+ for (normalization_steps = 0;
+ (long int) (big_base << normalization_steps) >= 0;
+ normalization_steps++)
+ ;
+ udiv_qrnnd (big_base_inverted, dummy,
+ -(big_base << normalization_steps), 0,
+ big_base << normalization_steps);
+ }
+ printf (" /* %2u */ {%lu, 0x%lX, 0x%lX, %.8f},\n",
+ i, idig, big_base, big_base_inverted, fdig);
+ }
+ puts ("};");
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/cre-mparam.c b/gnu/lib/libgmp/cre-mparam.c
new file mode 100644
index 0000000..ebb19d3
--- /dev/null
+++ b/gnu/lib/libgmp/cre-mparam.c
@@ -0,0 +1,121 @@
+/* cre-mparam.c -- Create machine-depedent parameter file.
+
+ $Id$
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+
+unsigned int
+ulog2 (unsigned long int x)
+{
+ unsigned int i;
+ for (i = 0; x != 0; i++)
+ x >>= 1;
+ return i;
+}
+
+void
+main (void)
+{
+ int i;
+
+ unsigned long int max_uli;
+ int bits_uli;
+
+ unsigned long int max_ui;
+ int bits_ui;
+
+ unsigned long int max_usi;
+ int bits_usi;
+
+ unsigned long int max_uc;
+ int bits_uc;
+
+ max_uli = 1;
+ for (i = 0; ; i++)
+ {
+ if (max_uli == 0)
+ break;
+ max_uli <<= 1;
+ }
+ bits_uli = i;
+
+ max_ui = 1;
+ for (i = 0; ; i++)
+ {
+ if ((unsigned int) max_ui == 0)
+ break;
+ max_ui <<= 1;
+ }
+ bits_ui = i;
+
+ max_usi = 1;
+ for (i = 0; ; i++)
+ {
+ if ((unsigned short int) max_usi == 0)
+ break;
+ max_usi <<= 1;
+ }
+ bits_usi = i;
+
+ max_uc = 1;
+ for (i = 0; ; i++)
+ {
+ if ((unsigned char) max_uc == 0)
+ break;
+ max_uc <<= 1;
+ }
+ bits_uc = i;
+
+ puts ("/* gmp-mparam.h -- Compiler/machine parameter header file.");
+ puts ("");
+ puts (" ***** THIS FILE WAS CREATED BY A PROGRAM. DON'T EDIT IT! *****");
+ puts ("");
+ puts ("Copyright (C) 1991 Free Software Foundation, Inc.");
+ puts ("");
+ puts ("This file is part of the GNU MP Library.");
+ puts ("");
+ puts ("The GNU MP Library is free software; you can redistribute it and/or");
+ puts ("modify it under the terms of the GNU General Public License as");
+ puts ("published by the Free Software Foundation; either version 2, or");
+ puts ("(at your option) any later version.");
+ puts ("");
+ puts ("The GNU MP Library is distributed in the hope that it will be");
+ puts ("useful, but WITHOUT ANY WARRANTY; without even the implied warranty");
+ puts ("of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the");
+ puts ("GNU General Public License for more details.");
+ puts ("");
+ puts ("You should have received a copy of the GNU General Public License");
+ puts ("along with the GNU MP Library; see the file COPYING. If not, write");
+ puts ("to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,");
+ puts ("USA. */");
+ puts ("");
+
+ printf ("#define BITS_PER_MP_LIMB %d\n", bits_uli);
+ printf ("#define BYTES_PER_MP_LIMB %d\n", sizeof(mp_limb));
+
+ printf ("#define BITS_PER_LONGINT %d\n", bits_uli);
+ printf ("#define BITS_PER_INT %d\n", bits_ui);
+ printf ("#define BITS_PER_SHORTINT %d\n", bits_usi);
+ printf ("#define BITS_PER_CHAR %d\n", bits_uc);
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/cre-stddefh.c b/gnu/lib/libgmp/cre-stddefh.c
new file mode 100644
index 0000000..4e1f862
--- /dev/null
+++ b/gnu/lib/libgmp/cre-stddefh.c
@@ -0,0 +1,42 @@
+/* cre-stddefh.c -- Check the size of a pointer and output an
+ appropriate size_t declaration.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ if (sizeof (int *) == sizeof (unsigned long int))
+ puts ("typedef unsigned long int size_t;");
+ else
+ if (sizeof (int *) == sizeof (unsigned int))
+ puts ("typedef unsigned int size_t;");
+ else
+ {
+ fprintf (stderr,
+ "%s: Can't find a reasonable definition for \"size_t\".\n",
+ argv[0]);
+ exit (1);
+ }
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/demos/factorize.c b/gnu/lib/libgmp/demos/factorize.c
new file mode 100644
index 0000000..4a965d3
--- /dev/null
+++ b/gnu/lib/libgmp/demos/factorize.c
@@ -0,0 +1,233 @@
+/* Factoring with Pollard's rho method.
+
+ Copyright (C) 1995 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; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+
+int flag_mersenne = 0;
+
+static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
+
+factor_using_division (t, limit)
+ mpz_t t;
+ unsigned int limit;
+{
+ mpz_t q, r;
+ unsigned long int f;
+ int i, ai;
+ unsigned *addv = add;
+
+ mpz_init (q);
+ mpz_init (r);
+
+ if (mpz_probab_prime_p (t, 50))
+ goto ready;
+
+ for (;;)
+ {
+ mpz_tdiv_qr_ui (q, r, t, 2);
+ if (mpz_cmp_ui (r, 0) != 0)
+ break;
+ mpz_set (t, q);
+ printf ("2 ");
+ fflush (stdout);
+ if (mpz_probab_prime_p (t, 50))
+ goto ready;
+ }
+
+ for (;;)
+ {
+ mpz_tdiv_qr_ui (q, r, t, 3);
+ if (mpz_cmp_ui (r, 0) != 0)
+ break;
+ mpz_set (t, q);
+ printf ("3 ");
+ fflush (stdout);
+ if (mpz_probab_prime_p (t, 50))
+ goto ready;
+ }
+
+ for (;;)
+ {
+ mpz_tdiv_qr_ui (q, r, t, 5);
+ if (mpz_cmp_ui (r, 0) != 0)
+ break;
+ mpz_set (t, q);
+ printf ("5 ");
+ fflush (stdout);
+ if (mpz_probab_prime_p (t, 50))
+ goto ready;
+ }
+
+ f = 7;
+ ai = 0;
+ for (;;)
+ {
+ mpz_tdiv_qr_ui (q, r, t, f);
+ if (mpz_cmp_ui (r, 0) != 0)
+ {
+ f += addv[ai];
+ if (f > limit)
+ goto ret;
+ ai = (ai + 1) & 7;
+ }
+ else
+ {
+ mpz_set (t, q);
+ printf ("%lu ", f);
+ fflush (stdout);
+ if (mpz_probab_prime_p (t, 50))
+ goto ready;
+ }
+ }
+
+ ready:
+ mpz_out_str (stdout, 10, t);
+ fflush (stdout);
+ mpz_set_ui (t, 1);
+ fputc (' ', stdout);
+ ret:
+ mpz_clear (q);
+ mpz_clear (r);
+}
+
+void
+factor_using_pollard_rho (m, a_int, x0, p)
+ mpz_t m;
+ long a_int;
+ long x0;
+ unsigned long p;
+{
+ mpz_t x, y, q;
+ mpz_t a;
+ mpz_t d;
+ mpz_t tmp;
+ mpz_t n;
+ int i = 1;
+ int j = 1;
+
+ mpz_init_set (n, m);
+
+ mpz_init (d);
+ mpz_init_set_ui (q, 1);
+ mpz_init (tmp);
+
+ mpz_init_set_si (a, a_int);
+ mpz_init_set_si (x, x0);
+ mpz_init_set_si (y, x0);
+
+ while (mpz_cmp_ui (n, 1) != 0)
+ {
+ if (flag_mersenne)
+ {
+ mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
+ mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);
+ mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);
+ }
+ else
+ {
+ mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
+ mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
+ mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
+ }
+
+ if (mpz_cmp (x, y) > 0)
+ mpz_sub (tmp, x, y);
+ else
+ mpz_sub (tmp, y, x);
+ mpz_mul (q, q, tmp);
+ mpz_mod (q, q, n);
+
+ if (++i % j == 0)
+ {
+ j += 1;
+ mpz_gcd (d, q, n);
+ if (mpz_cmp_ui (d, 1) != 0)
+ {
+ if (!mpz_probab_prime_p (d, 50))
+ factor_using_pollard_rho (d, (random () & 31) - 16,
+ (random () & 31), p);
+ else
+ {
+ mpz_out_str (stdout, 10, d);
+ fflush (stdout);
+ fputc (' ', stdout);
+ }
+ mpz_div (n, n, d);
+ if (mpz_probab_prime_p (n, 50))
+ {
+ mpz_out_str (stdout, 10, n);
+ fflush (stdout);
+ fputc (' ', stdout);
+ break;
+ }
+ }
+ }
+ }
+
+ mpz_clear (n);
+ mpz_clear (d);
+ mpz_clear (q);
+ mpz_clear (tmp);
+ mpz_clear (a);
+ mpz_clear (x);
+ mpz_clear (y);
+}
+
+factor (t, a, x0, p)
+ mpz_t t;
+ long a;
+ long x0;
+ unsigned long p;
+{
+ factor_using_division (t, 1000000);
+ factor_using_pollard_rho (t, a, x0, p);
+}
+
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ mpz_t t;
+ long x0, a;
+ unsigned long p;
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if (!strncmp (argv[i], "-Mp", 3))
+ {
+ p = atoi (argv[i] + 3);
+ mpz_init_set_ui (t, 1);
+ mpz_mul_2exp (t, t, p);
+ mpz_sub_ui (t, t, 1);
+ flag_mersenne = 1;
+ }
+ else
+ {
+ p = 0;
+ mpz_init_set_str (t, argv[i], 0);
+ }
+
+ a = -1;
+ x0 = 3;
+
+ factor (t, a, x0, p);
+ puts ("");
+ }
+}
diff --git a/gnu/lib/libgmp/doc/Makefile b/gnu/lib/libgmp/doc/Makefile
new file mode 100644
index 0000000..3d1f0fe
--- /dev/null
+++ b/gnu/lib/libgmp/doc/Makefile
@@ -0,0 +1,7 @@
+# $Id$
+
+INFO= gmp
+
+.PATH: ${.CURDIR}/..
+
+.include <bsd.info.mk>
diff --git a/gnu/lib/libgmp/extract-double.c b/gnu/lib/libgmp/extract-double.c
new file mode 100644
index 0000000..052b1a9
--- /dev/null
+++ b/gnu/lib/libgmp/extract-double.c
@@ -0,0 +1,160 @@
+/* __gmp_extract_double -- convert from double to array of mp_limb_t.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef XDEBUG
+#undef _GMP_IEEE_FLOATS
+#endif
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+#define MP_BASE_AS_DOUBLE (2.0 * ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1)))
+
+/* Extract a non-negative double in d. */
+
+int
+#if __STDC__
+__gmp_extract_double (mp_ptr rp, double d)
+#else
+__gmp_extract_double (rp, d)
+ mp_ptr rp;
+ double d;
+#endif
+{
+ long exp;
+ unsigned sc;
+ mp_limb_t manh, manl;
+
+ /* BUGS
+
+ 1. Should handle Inf and NaN in IEEE specific code.
+ 2. Handle Inf and NaN also in default code, to avoid hangs.
+ 3. Generalize to handle all BITS_PER_MP_LIMB >= 32.
+ 4. This lits is incomplete and misspelled.
+ */
+
+ if (d == 0.0)
+ {
+ rp[0] = 0;
+ rp[1] = 0;
+#if BITS_PER_MP_LIMB == 32
+ rp[2] = 0;
+#endif
+ return 0;
+ }
+
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract x;
+ x.d = d;
+
+ exp = x.s.exp;
+ sc = (unsigned) (exp + 2) % BITS_PER_MP_LIMB;
+#if BITS_PER_MP_LIMB == 64
+ manl = (((mp_limb_t) 1 << 63)
+ | ((mp_limb_t) x.s.manh << 43) | ((mp_limb_t) x.s.manl << 11));
+#else
+ manh = ((mp_limb_t) 1 << 31) | (x.s.manh << 11) | (x.s.manl >> 21);
+ manl = x.s.manl << 11;
+#endif
+ }
+#else
+ {
+ /* Unknown (or known to be non-IEEE) double format. */
+ exp = 0;
+ if (d >= 1.0)
+ {
+ if (d * 0.5 == d)
+ abort ();
+
+ while (d >= 32768.0)
+ {
+ d *= (1.0 / 65536.0);
+ exp += 16;
+ }
+ while (d >= 1.0)
+ {
+ d *= 0.5;
+ exp += 1;
+ }
+ }
+ else if (d < 0.5)
+ {
+ while (d < (1.0 / 65536.0))
+ {
+ d *= 65536.0;
+ exp -= 16;
+ }
+ while (d < 0.5)
+ {
+ d *= 2.0;
+ exp -= 1;
+ }
+ }
+
+ sc = (unsigned) exp % BITS_PER_MP_LIMB;
+
+ d *= MP_BASE_AS_DOUBLE;
+#if BITS_PER_MP_LIMB == 64
+ manl = d;
+#else
+ manh = d;
+ manl = (d - manh) * MP_BASE_AS_DOUBLE;
+#endif
+
+ exp += 1022;
+ }
+#endif
+
+ exp = (unsigned) (exp + 1) / BITS_PER_MP_LIMB - 1024 / BITS_PER_MP_LIMB + 1;
+
+#if BITS_PER_MP_LIMB == 64
+ if (sc != 0)
+ {
+ rp[1] = manl >> (BITS_PER_MP_LIMB - sc);
+ rp[0] = manl << sc;
+ }
+ else
+ {
+ rp[1] = manl;
+ rp[0] = 0;
+ }
+#else
+ if (sc != 0)
+ {
+ rp[2] = manh >> (BITS_PER_MP_LIMB - sc);
+ rp[1] = (manl >> (BITS_PER_MP_LIMB - sc)) | (manh << sc);
+ rp[0] = manl << sc;
+ }
+ else
+ {
+ rp[2] = manh;
+ rp[1] = manl;
+ rp[0] = 0;
+ }
+#endif
+
+ return exp;
+}
diff --git a/gnu/lib/libgmp/gmp-impl.h b/gnu/lib/libgmp/gmp-impl.h
new file mode 100644
index 0000000..7d56846
--- /dev/null
+++ b/gnu/lib/libgmp/gmp-impl.h
@@ -0,0 +1,367 @@
+/* Include file for internal GNU MP types and definitions.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* When using gcc, make sure to use its builtin alloca. */
+#if ! defined (alloca) && defined (__GNUC__)
+#define alloca __builtin_alloca
+#define HAVE_ALLOCA
+#endif
+
+/* When using cc, do whatever necessary to allow use of alloca. For many
+ machines, this means including alloca.h. IBM's compilers need a #pragma
+ in "each module that needs to use alloca". */
+#if ! defined (alloca)
+/* We need lots of variants for MIPS, to cover all versions and perversions
+ of OSes for MIPS. */
+#if defined (__mips) || defined (MIPSEL) || defined (MIPSEB) \
+ || defined (_MIPSEL) || defined (_MIPSEB) || defined (__sgi) \
+ || defined (__alpha) || defined (__sparc) || defined (sparc) \
+ || defined (__ksr__)
+#include <alloca.h>
+#define HAVE_ALLOCA
+#endif
+#if defined (_IBMR2)
+#pragma alloca
+#define HAVE_ALLOCA
+#endif
+#if defined (__DECC)
+#define alloca(x) __ALLOCA(x)
+#define HAVE_ALLOCA
+#endif
+#endif
+
+#if ! defined (HAVE_ALLOCA) || USE_STACK_ALLOC
+#include "stack-alloc.h"
+#else
+#define TMP_DECL(m)
+#define TMP_ALLOC(x) alloca(x)
+#define TMP_MARK(m)
+#define TMP_FREE(m)
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#if ! defined (__GNUC__)
+#define inline /* Empty */
+#endif
+
+#define ABS(x) (x >= 0 ? x : -x)
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+
+/* Field access macros. */
+#define SIZ(x) ((x)->_mp_size)
+#define ABSIZ(x) ABS (SIZ (x))
+#define PTR(x) ((x)->_mp_d)
+#define EXP(x) ((x)->_mp_exp)
+#define PREC(x) ((x)->_mp_prec)
+#define ALLOC(x) ((x)->_mp_alloc)
+
+#include "gmp-mparam.h"
+/* #include "longlong.h" */
+
+#if defined (__STDC__) || defined (__cplusplus)
+void *malloc (size_t);
+void *realloc (void *, size_t);
+void free (void *);
+
+extern void * (*_mp_allocate_func) (size_t);
+extern void * (*_mp_reallocate_func) (void *, size_t, size_t);
+extern void (*_mp_free_func) (void *, size_t);
+
+void *_mp_default_allocate (size_t);
+void *_mp_default_reallocate (void *, size_t, size_t);
+void _mp_default_free (void *, size_t);
+
+#else
+
+#define const /* Empty */
+#define signed /* Empty */
+
+void *malloc ();
+void *realloc ();
+void free ();
+
+extern void * (*_mp_allocate_func) ();
+extern void * (*_mp_reallocate_func) ();
+extern void (*_mp_free_func) ();
+
+void *_mp_default_allocate ();
+void *_mp_default_reallocate ();
+void _mp_default_free ();
+#endif
+
+/* Copy NLIMBS *limbs* from SRC to DST. */
+#define MPN_COPY_INCR(DST, SRC, NLIMBS) \
+ do { \
+ mp_size_t __i; \
+ for (__i = 0; __i < (NLIMBS); __i++) \
+ (DST)[__i] = (SRC)[__i]; \
+ } while (0)
+#define MPN_COPY_DECR(DST, SRC, NLIMBS) \
+ do { \
+ mp_size_t __i; \
+ for (__i = (NLIMBS) - 1; __i >= 0; __i--) \
+ (DST)[__i] = (SRC)[__i]; \
+ } while (0)
+#define MPN_COPY MPN_COPY_INCR
+
+/* Zero NLIMBS *limbs* AT DST. */
+#define MPN_ZERO(DST, NLIMBS) \
+ do { \
+ mp_size_t __i; \
+ for (__i = 0; __i < (NLIMBS); __i++) \
+ (DST)[__i] = 0; \
+ } while (0)
+
+#define MPN_NORMALIZE(DST, NLIMBS) \
+ do { \
+ while (NLIMBS > 0) \
+ { \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ NLIMBS--; \
+ } \
+ } while (0)
+#define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
+ do { \
+ while (1) \
+ { \
+ if ((DST)[(NLIMBS) - 1] != 0) \
+ break; \
+ NLIMBS--; \
+ } \
+ } while (0)
+
+/* Initialize the MP_INT X with space for NLIMBS limbs.
+ X should be a temporary variable, and it will be automatically
+ cleared out when the running function returns.
+ We use __x here to make it possible to accept both mpz_ptr and mpz_t
+ arguments. */
+#define MPZ_TMP_INIT(X, NLIMBS) \
+ do { \
+ mpz_ptr __x = (X); \
+ __x->_mp_alloc = (NLIMBS); \
+ __x->_mp_d = (mp_ptr) TMP_ALLOC ((NLIMBS) * BYTES_PER_MP_LIMB); \
+ } while (0)
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ impn_mul_n_basecase (prodp, up, vp, size); \
+ else \
+ impn_mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ impn_sqr_n_basecase (prodp, up, size); \
+ else \
+ impn_sqr_n (prodp, up, size, tspace); \
+ } while (0);
+
+/* Structure for conversion between internal binary format and
+ strings in base 2..36. */
+struct bases
+{
+ /* Number of digits in the conversion base that always fits in an mp_limb_t.
+ For example, for base 10 on a machine where a mp_limb_t has 32 bits this
+ is 9, since 10**9 is the largest number that fits into a mp_limb_t. */
+ int chars_per_limb;
+
+ /* log(2)/log(conversion_base) */
+ float chars_per_bit_exactly;
+
+ /* base**chars_per_limb, i.e. the biggest number that fits a word, built by
+ factors of base. Exception: For 2, 4, 8, etc, big_base is log2(base),
+ i.e. the number of bits used to represent each digit in the base. */
+ mp_limb_t big_base;
+
+ /* A BITS_PER_MP_LIMB bit approximation to 1/big_base, represented as a
+ fixed-point number. Instead of dividing by big_base an application can
+ choose to multiply by big_base_inverted. */
+ mp_limb_t big_base_inverted;
+};
+
+extern const struct bases __mp_bases[];
+extern mp_size_t __gmp_default_fp_limb_precision;
+
+/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
+ limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
+ If this would yield overflow, DI should be the largest possible number
+ (i.e., only ones). For correct operation, the most significant bit of D
+ has to be set. Put the quotient in Q and the remainder in R. */
+#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
+ do { \
+ mp_limb_t _q, _ql, _r; \
+ mp_limb_t _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MP_LIMB too small */\
+ umul_ppmm (_xh, _xl, _q, (d)); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ } \
+ } \
+ if (_r >= (d)) \
+ { \
+ _r -= (d); \
+ _q += 1; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+/* Like udiv_qrnnd_preinv, but for for any value D. DNORM is D shifted left
+ so that its most significant bit is set. LGUP is ceil(log2(D)). */
+#define udiv_qrnnd_preinv2gen(q, r, nh, nl, d, di, dnorm, lgup) \
+ do { \
+ mp_limb_t n2, n10, n1, nadj, q1; \
+ mp_limb_t _xh, _xl; \
+ n2 = ((nh) << (BITS_PER_MP_LIMB - (lgup))) + ((nl) >> 1 >> (l - 1));\
+ n10 = (nl) << (BITS_PER_MP_LIMB - (lgup)); \
+ n1 = ((mp_limb_signed_t) n10 >> (BITS_PER_MP_LIMB - 1)); \
+ nadj = n10 + (n1 & (dnorm)); \
+ umul_ppmm (_xh, _xl, di, n2 - n1); \
+ add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \
+ q1 = ~(n2 + _xh); \
+ umul_ppmm (_xh, _xl, q1, d); \
+ add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \
+ _xh -= (d); \
+ (r) = _xl + ((d) & _xh); \
+ (q) = _xh - q1; \
+ } while (0)
+/* Exactly like udiv_qrnnd_preinv, but branch-free. It is not clear which
+ version to use. */
+#define udiv_qrnnd_preinv2norm(q, r, nh, nl, d, di) \
+ do { \
+ mp_limb_t n2, n10, n1, nadj, q1; \
+ mp_limb_t _xh, _xl; \
+ n2 = (nh); \
+ n10 = (nl); \
+ n1 = ((mp_limb_signed_t) n10 >> (BITS_PER_MP_LIMB - 1)); \
+ nadj = n10 + (n1 & (d)); \
+ umul_ppmm (_xh, _xl, di, n2 - n1); \
+ add_ssaaaa (_xh, _xl, _xh, _xl, 0, nadj); \
+ q1 = ~(n2 + _xh); \
+ umul_ppmm (_xh, _xl, q1, d); \
+ add_ssaaaa (_xh, _xl, _xh, _xl, nh, nl); \
+ _xh -= (d); \
+ (r) = _xl + ((d) & _xh); \
+ (q) = _xh - q1; \
+ } while (0)
+
+#if defined (__GNUC__)
+/* Define stuff for longlong.h. */
+typedef unsigned int UQItype __attribute__ ((mode (QI)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef unsigned int USItype __attribute__ ((mode (SI)));
+typedef int DItype __attribute__ ((mode (DI)));
+typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+typedef unsigned char UQItype;
+typedef long SItype;
+typedef unsigned long USItype;
+#endif
+
+typedef mp_limb_t UWtype;
+typedef unsigned int UHWtype;
+#define W_TYPE_SIZE BITS_PER_MP_LIMB
+
+/* Internal mpn calls */
+#define impn_mul_n_basecase __MPN(impn_mul_n_basecase)
+#define impn_mul_n __MPN(impn_mul_n)
+#define impn_sqr_n_basecase __MPN(impn_sqr_n_basecase)
+#define impn_sqr_n __MPN(impn_sqr_n)
+
+/* Define ieee_double_extract and _GMP_IEEE_FLOATS. */
+
+#if defined (_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__) \
+ || defined (__alpha) \
+ || (defined (__arm__) && defined (__ARMWEL__)) \
+ || defined (__clipper__) \
+ || defined (__cris) \
+ || defined (__i386__) \
+ || defined (__i860__) \
+ || defined (__i960__) \
+ || defined (MIPSEL) || defined (_MIPSEL) \
+ || defined (__ns32000__) \
+ || defined (__WINNT) || defined (_WIN32)
+#define _GMP_IEEE_FLOATS 1
+union ieee_double_extract
+{
+ struct
+ {
+ unsigned int manl:32;
+ unsigned int manh:20;
+ unsigned int exp:11;
+ unsigned int sig:1;
+ } s;
+ double d;
+};
+#else /* Need this as an #else since the tests aren't made exclusive. */
+#if defined (_BIG_ENDIAN) \
+ || defined (__a29k__) || defined (_AM29K) \
+ || defined (__arm__) \
+ || (defined (__convex__) && defined (_IEEE_FLOAT_)) \
+ || defined (__i370__) || defined (__mvs__) \
+ || defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__)\
+ || defined(mc68020) \
+ || defined (__m88000__) \
+ || defined (MIPSEB) || defined (_MIPSEB) \
+ || defined (__hppa) \
+ || defined (__pyr__) \
+ || defined (__ibm032__) \
+ || defined (_IBMR2) || defined (_ARCH_PPC) \
+ || defined (__sh__) \
+ || defined (__sparc) || defined (sparc) \
+ || defined (__we32k__)
+#define _GMP_IEEE_FLOATS 1
+union ieee_double_extract
+{
+ struct
+ {
+ unsigned int sig:1;
+ unsigned int exp:11;
+ unsigned int manh:20;
+ unsigned int manl:32;
+ } s;
+ double d;
+};
+#endif
+#endif
+
+#define MP_BASE_AS_DOUBLE (2.0 * ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1)))
+#if BITS_PER_MP_LIMB == 64
+#define LIMBS_PER_DOUBLE 2
+#else
+#define LIMBS_PER_DOUBLE 3
+#endif
+
+double __gmp_scale2 _PROTO ((double, int));
+int __gmp_extract_double _PROTO((mp_ptr, double));
diff --git a/gnu/lib/libgmp/gmp.h b/gnu/lib/libgmp/gmp.h
new file mode 100644
index 0000000..a1cc1ac
--- /dev/null
+++ b/gnu/lib/libgmp/gmp.h
@@ -0,0 +1,632 @@
+/* gmp.h -- Definitions for GNU multiple precision functions.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#ifndef __GMP_H__
+
+#ifndef __GNU_MP__
+#define __GNU_MP__ 2
+#define __need_size_t
+#include <stddef.h>
+#undef __need_size_t
+
+#if defined (__STDC__) || defined (__cplusplus)
+#define __gmp_const const
+#else
+#define __gmp_const
+#endif
+
+#if defined (__GNUC__)
+#define __gmp_inline __inline__
+#else
+#define __gmp_inline
+#endif
+
+#ifndef _EXTERN_INLINE
+#ifdef __GNUC__
+#define _EXTERN_INLINE extern __inline__
+#else
+#define _EXTERN_INLINE static
+#endif
+#endif
+
+#ifdef _SHORT_LIMB
+typedef unsigned int mp_limb_t;
+typedef int mp_limb_signed_t;
+#else
+#ifdef _LONG_LONG_LIMB
+typedef unsigned long long int mp_limb_t;
+typedef long long int mp_limb_signed_t;
+#else
+typedef unsigned long int mp_limb_t;
+typedef long int mp_limb_signed_t;
+#endif
+#endif
+
+typedef mp_limb_t * mp_ptr;
+typedef __gmp_const mp_limb_t * mp_srcptr;
+typedef long int mp_size_t;
+typedef long int mp_exp_t;
+
+#ifndef __MP_SMALL__
+typedef struct
+{
+ int _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the D field. */
+ int _mp_size; /* abs(SIZE) is the number of limbs
+ the last field points to. If SIZE
+ is negative this is a negative
+ number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+#else
+typedef struct
+{
+ short int _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the D field. */
+ short int _mp_size; /* abs(SIZE) is the number of limbs
+ the last field points to. If SIZE
+ is negative this is a negative
+ number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+#endif
+#endif /* __GNU_MP__ */
+
+/* User-visible types. */
+typedef __mpz_struct MP_INT;
+typedef __mpz_struct mpz_t[1];
+
+/* Structure for rational numbers. Zero is represented as 0/any, i.e.
+ the denominator is ignored. Negative numbers have the sign in
+ the numerator. */
+typedef struct
+{
+ __mpz_struct _mp_num;
+ __mpz_struct _mp_den;
+#if 0
+ int _mp_num_alloc; /* Number of limbs allocated
+ for the numerator. */
+ int _mp_num_size; /* The absolute value of this field is the
+ length of the numerator; the sign is the
+ sign of the entire rational number. */
+ mp_ptr _mp_num; /* Pointer to the numerator limbs. */
+ int _mp_den_alloc; /* Number of limbs allocated
+ for the denominator. */
+ int _mp_den_size; /* Length of the denominator. (This field
+ should always be positive.) */
+ mp_ptr _mp_den; /* Pointer to the denominator limbs. */
+#endif
+} __mpq_struct;
+
+typedef __mpq_struct MP_RAT;
+typedef __mpq_struct mpq_t[1];
+
+typedef struct
+{
+ int _mp_prec; /* Max precision, in number of `mp_limb_t's.
+ Set by mpf_init and modified by
+ mpf_set_prec. The area pointed to
+ by the `d' field contains `prec' + 1
+ limbs. */
+ int _mp_size; /* abs(SIZE) is the number of limbs
+ the last field points to. If SIZE
+ is negative this is a negative
+ number. */
+ mp_exp_t _mp_exp; /* Exponent, in the base of `mp_limb_t'. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpf_struct;
+
+/* typedef __mpf_struct MP_FLOAT; */
+typedef __mpf_struct mpf_t[1];
+
+/* Types for function declarations in gmp files. */
+/* ??? Should not pollute user name space with these ??? */
+typedef __gmp_const __mpz_struct *mpz_srcptr;
+typedef __mpz_struct *mpz_ptr;
+typedef __gmp_const __mpf_struct *mpf_srcptr;
+typedef __mpf_struct *mpf_ptr;
+typedef __gmp_const __mpq_struct *mpq_srcptr;
+typedef __mpq_struct *mpq_ptr;
+
+#ifndef _PROTO
+#if defined (__STDC__) || defined (__cplusplus)
+#define _PROTO(x) x
+#else
+#define _PROTO(x) ()
+#endif
+#endif
+
+#ifndef __MPN
+#if defined (__STDC__) || defined (__cplusplus)
+#define __MPN(x) __mpn_##x
+#else
+#define __MPN(x) __mpn_/**/x
+#endif
+#endif
+
+#if defined (FILE) || defined (H_STDIO) || defined (_H_STDIO) \
+ || defined (_STDIO_H) || defined (_STDIO_H_) || defined (__STDIO_H__) \
+ || defined (_STDIO_INCLUDED)
+#define _GMP_H_HAVE_FILE 1
+#endif
+
+void mp_set_memory_functions _PROTO ((void *(*) (size_t),
+ void *(*) (void *, size_t, size_t),
+ void (*) (void *, size_t)));
+extern __gmp_const int mp_bits_per_limb;
+
+/**************** Integer (i.e. Z) routines. ****************/
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+void *_mpz_realloc _PROTO ((mpz_ptr, mp_size_t));
+
+void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_add _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_and _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_array_init _PROTO ((mpz_ptr, mp_size_t, mp_size_t));
+void mpz_cdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+unsigned long int mpz_cdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_cdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+unsigned long int mpz_cdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_cdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+unsigned long int mpz_cdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_cdiv_ui _PROTO ((mpz_srcptr, unsigned long int));
+void mpz_clear _PROTO ((mpz_ptr));
+void mpz_clrbit _PROTO ((mpz_ptr, unsigned long int));
+int mpz_cmp _PROTO ((mpz_srcptr, mpz_srcptr));
+int mpz_cmp_si _PROTO ((mpz_srcptr, signed long int));
+int mpz_cmp_ui _PROTO ((mpz_srcptr, unsigned long int));
+void mpz_com _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_divexact _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_fac_ui _PROTO ((mpz_ptr, unsigned long int));
+void mpz_fdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_fdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_fdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+unsigned long int mpz_fdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_fdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_fdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_ui _PROTO ((mpz_srcptr, unsigned long int));
+void mpz_gcd _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+double mpz_get_d _PROTO ((mpz_srcptr));
+/* signed */ long int mpz_get_si _PROTO ((mpz_srcptr));
+char *mpz_get_str _PROTO ((char *, int, mpz_srcptr));
+unsigned long int mpz_get_ui _PROTO ((mpz_srcptr));
+mp_limb_t mpz_getlimbn _PROTO ((mpz_srcptr, mp_size_t));
+unsigned long int mpz_hamdist _PROTO ((mpz_srcptr, mpz_srcptr));
+void mpz_init _PROTO ((mpz_ptr));
+#ifdef _GMP_H_HAVE_FILE
+size_t mpz_inp_binary _PROTO ((mpz_ptr, FILE *));
+size_t mpz_inp_raw _PROTO ((mpz_ptr, FILE *));
+size_t mpz_inp_str _PROTO ((mpz_ptr, FILE *, int));
+#endif
+void mpz_init_set _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_init_set_d _PROTO ((mpz_ptr, double));
+void mpz_init_set_si _PROTO ((mpz_ptr, signed long int));
+int mpz_init_set_str _PROTO ((mpz_ptr, const char *, int));
+void mpz_init_set_ui _PROTO ((mpz_ptr, unsigned long int));
+int mpz_invert _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_ior _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+int mpz_jacobi _PROTO ((mpz_srcptr, mpz_srcptr));
+int mpz_legendre _PROTO ((mpz_srcptr, mpz_srcptr));
+void mpz_mod _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_mul _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr));
+#ifdef _GMP_H_HAVE_FILE
+size_t mpz_out_binary _PROTO ((FILE *, mpz_srcptr));
+size_t mpz_out_raw _PROTO ((FILE *, mpz_srcptr));
+size_t mpz_out_str _PROTO ((FILE *, int, mpz_srcptr));
+#endif
+int mpz_perfect_square_p _PROTO ((mpz_srcptr));
+unsigned long int mpz_popcount _PROTO ((mpz_srcptr));
+void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr));
+void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr));
+int mpz_probab_prime_p _PROTO ((mpz_srcptr, int));
+void mpz_random _PROTO ((mpz_ptr, mp_size_t));
+void mpz_random2 _PROTO ((mpz_ptr, mp_size_t));
+unsigned long int mpz_scan0 _PROTO ((mpz_srcptr, unsigned long int));
+unsigned long int mpz_scan1 _PROTO ((mpz_srcptr, unsigned long int));
+void mpz_set _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_set_d _PROTO ((mpz_ptr, double));
+void mpz_set_f _PROTO ((mpz_ptr, mpf_srcptr));
+void mpz_set_q _PROTO ((mpz_ptr, mpq_srcptr));
+void mpz_set_si _PROTO ((mpz_ptr, signed long int));
+int mpz_set_str _PROTO ((mpz_ptr, const char *, int));
+void mpz_set_ui _PROTO ((mpz_ptr, unsigned long int));
+void mpz_setbit _PROTO ((mpz_ptr, unsigned long int));
+size_t mpz_size _PROTO ((mpz_srcptr));
+size_t mpz_sizeinbase _PROTO ((mpz_srcptr, int));
+void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr));
+void mpz_sub _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_q _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_tdiv_q_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_tdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_r _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_tdiv_r_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_ui_pow_ui _PROTO ((mpz_ptr, unsigned long int, unsigned long int));
+
+/**************** Rational (i.e. Q) routines. ****************/
+
+void mpq_init _PROTO ((mpq_ptr));
+void mpq_clear _PROTO ((mpq_ptr));
+void mpq_set _PROTO ((mpq_ptr, mpq_srcptr));
+void mpq_set_ui _PROTO ((mpq_ptr, unsigned long int, unsigned long int));
+void mpq_set_si _PROTO ((mpq_ptr, signed long int, unsigned long int));
+void mpq_set_z _PROTO ((mpq_ptr, mpz_srcptr));
+void mpq_add _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
+void mpq_sub _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
+void mpq_mul _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
+void mpq_div _PROTO ((mpq_ptr, mpq_srcptr, mpq_srcptr));
+void mpq_neg _PROTO ((mpq_ptr, mpq_srcptr));
+int mpq_cmp _PROTO ((mpq_srcptr, mpq_srcptr));
+int mpq_cmp_ui _PROTO ((mpq_srcptr, unsigned long int, unsigned long int));
+int mpq_equal _PROTO ((mpq_srcptr, mpq_srcptr));
+void mpq_inv _PROTO ((mpq_ptr, mpq_srcptr));
+void mpq_set_num _PROTO ((mpq_ptr, mpz_srcptr));
+void mpq_set_den _PROTO ((mpq_ptr, mpz_srcptr));
+void mpq_get_num _PROTO ((mpz_ptr, mpq_srcptr));
+void mpq_get_den _PROTO ((mpz_ptr, mpq_srcptr));
+double mpq_get_d _PROTO ((mpq_srcptr));
+void mpq_canonicalize _PROTO ((mpq_ptr));
+
+/**************** Float (i.e. F) routines. ****************/
+
+void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_add _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
+void mpf_add_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_clear _PROTO ((mpf_ptr));
+int mpf_cmp _PROTO ((mpf_srcptr, mpf_srcptr));
+int mpf_cmp_si _PROTO ((mpf_srcptr, signed long int));
+int mpf_cmp_ui _PROTO ((mpf_srcptr, unsigned long int));
+void mpf_div _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
+void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_div_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_dump _PROTO ((mpf_srcptr));
+int mpf_eq _PROTO ((mpf_srcptr, mpf_srcptr, unsigned long int));
+double mpf_get_d _PROTO ((mpf_srcptr));
+unsigned long int mpf_get_prec _PROTO ((mpf_srcptr));
+char *mpf_get_str _PROTO ((char *, mp_exp_t *, int, size_t, mpf_srcptr));
+void mpf_init _PROTO ((mpf_ptr));
+void mpf_init2 _PROTO ((mpf_ptr, unsigned long int));
+#ifdef _GMP_H_HAVE_FILE
+size_t mpf_inp_str _PROTO ((mpf_ptr, FILE *, int));
+#endif
+void mpf_init_set _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_init_set_d _PROTO ((mpf_ptr, double));
+void mpf_init_set_si _PROTO ((mpf_ptr, signed long int));
+int mpf_init_set_str _PROTO ((mpf_ptr, const char *, int));
+void mpf_init_set_ui _PROTO ((mpf_ptr, unsigned long int));
+void mpf_mul _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
+void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_mul_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr));
+#ifdef _GMP_H_HAVE_FILE
+size_t mpf_out_str _PROTO ((FILE *, int, size_t, mpf_srcptr));
+#endif
+void mpf_random2 _PROTO ((mpf_ptr, mp_size_t, mp_exp_t));
+void mpf_reldiff _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
+void mpf_set _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_set_d _PROTO ((mpf_ptr, double));
+void mpf_set_default_prec _PROTO ((unsigned long int));
+void mpf_set_prec _PROTO ((mpf_ptr, unsigned long int));
+void mpf_set_prec_raw _PROTO ((mpf_ptr, unsigned long int));
+void mpf_set_q _PROTO ((mpf_ptr, mpq_srcptr));
+void mpf_set_si _PROTO ((mpf_ptr, signed long int));
+int mpf_set_str _PROTO ((mpf_ptr, const char *, int));
+void mpf_set_ui _PROTO ((mpf_ptr, unsigned long int));
+void mpf_set_z _PROTO ((mpf_ptr, mpz_srcptr));
+size_t mpf_size _PROTO ((mpf_srcptr));
+void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_sqrt_ui _PROTO ((mpf_ptr, unsigned long int));
+void mpf_sub _PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
+void mpf_sub_ui _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_ui_div _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr));
+void mpf_ui_sub _PROTO ((mpf_ptr, unsigned long int, mpf_srcptr));
+#if defined (__cplusplus)
+}
+#endif
+/************ Low level positive-integer (i.e. N) routines. ************/
+
+/* This is ugly, but we need to make usr calls reach the prefixed function. */
+#define mpn_add __MPN(add)
+#define mpn_add_1 __MPN(add_1)
+#define mpn_add_n __MPN(add_n)
+#define mpn_addmul_1 __MPN(addmul_1)
+#define mpn_bdivmod __MPN(bdivmod)
+#define mpn_cmp __MPN(cmp)
+#define mpn_divmod_1 __MPN(divmod_1)
+#define mpn_divrem __MPN(divrem)
+#define mpn_divrem_1 __MPN(divrem_1)
+#define mpn_dump __MPN(dump)
+#define mpn_gcd __MPN(gcd)
+#define mpn_gcd_1 __MPN(gcd_1)
+#define mpn_gcdext __MPN(gcdext)
+#define mpn_get_str __MPN(get_str)
+#define mpn_hamdist __MPN(hamdist)
+#define mpn_lshift __MPN(lshift)
+#define mpn_mod_1 __MPN(mod_1)
+#define mpn_mul __MPN(mul)
+#define mpn_mul_1 __MPN(mul_1)
+#define mpn_mul_n __MPN(mul_n)
+#define mpn_perfect_square_p __MPN(perfect_square_p)
+#define mpn_popcount __MPN(popcount)
+#define mpn_preinv_mod_1 __MPN(preinv_mod_1)
+#define mpn_random2 __MPN(random2)
+#define mpn_rshift __MPN(rshift)
+#define mpn_scan0 __MPN(scan0)
+#define mpn_scan1 __MPN(scan1)
+#define mpn_set_str __MPN(set_str)
+#define mpn_sqrtrem __MPN(sqrtrem)
+#define mpn_sub __MPN(sub)
+#define mpn_sub_1 __MPN(sub_1)
+#define mpn_sub_n __MPN(sub_n)
+#define mpn_submul_1 __MPN(submul_1)
+#define mpn_udiv_w_sdiv __MPN(udiv_w_sdiv)
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+mp_limb_t mpn_add _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
+mp_limb_t mpn_add_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+mp_limb_t mpn_add_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
+mp_limb_t mpn_addmul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+mp_limb_t mpn_bdivmod _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_srcptr, mp_size_t, unsigned long int));
+int mpn_cmp _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
+mp_limb_t mpn_divmod_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+mp_limb_t mpn_divrem _PROTO ((mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr, mp_size_t));
+mp_limb_t mpn_divrem_1 _PROTO ((mp_ptr, mp_size_t, mp_srcptr, mp_size_t, mp_limb_t));
+void mpn_dump _PROTO ((mp_srcptr, mp_size_t));
+mp_size_t mpn_gcd _PROTO ((mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
+mp_limb_t mpn_gcd_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
+mp_size_t mpn_gcdext _PROTO ((mp_ptr, mp_ptr, mp_ptr, mp_size_t, mp_ptr, mp_size_t));
+size_t mpn_get_str _PROTO ((unsigned char *, int, mp_ptr, mp_size_t));
+unsigned long int mpn_hamdist _PROTO ((mp_srcptr, mp_srcptr, mp_size_t));
+mp_limb_t mpn_lshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
+mp_limb_t mpn_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t));
+mp_limb_t mpn_mul _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t));
+mp_limb_t mpn_mul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+void mpn_mul_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
+int mpn_perfect_square_p _PROTO ((mp_srcptr, mp_size_t));
+unsigned long int mpn_popcount _PROTO ((mp_srcptr, mp_size_t));
+mp_limb_t mpn_preinv_mod_1 _PROTO ((mp_srcptr, mp_size_t, mp_limb_t, mp_limb_t));
+void mpn_random2 _PROTO ((mp_ptr, mp_size_t));
+mp_limb_t mpn_rshift _PROTO ((mp_ptr, mp_srcptr, mp_size_t, unsigned int));
+unsigned long int mpn_scan0 _PROTO ((mp_srcptr, unsigned long int));
+unsigned long int mpn_scan1 _PROTO ((mp_srcptr, unsigned long int));
+mp_size_t mpn_set_str _PROTO ((mp_ptr, const unsigned char *, size_t, int));
+mp_size_t mpn_sqrtrem _PROTO ((mp_ptr, mp_ptr, mp_srcptr, mp_size_t));
+mp_limb_t mpn_sub _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_srcptr,mp_size_t));
+mp_limb_t mpn_sub_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+mp_limb_t mpn_sub_n _PROTO ((mp_ptr, mp_srcptr, mp_srcptr, mp_size_t));
+mp_limb_t mpn_submul_1 _PROTO ((mp_ptr, mp_srcptr, mp_size_t, mp_limb_t));
+#if defined (__cplusplus)
+}
+#endif
+
+#if defined (__GNUC__) || defined (_FORCE_INLINES)
+_EXTERN_INLINE mp_limb_t
+#if defined (__STDC__) || defined (__cplusplus)
+mpn_add_1 (register mp_ptr res_ptr,
+ register mp_srcptr s1_ptr,
+ register mp_size_t s1_size,
+ register mp_limb_t s2_limb)
+#else
+mpn_add_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+#endif
+{
+ register mp_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x + s2_limb;
+ *res_ptr++ = s2_limb;
+ if (s2_limb < x)
+ {
+ while (--s1_size != 0)
+ {
+ x = *s1_ptr++ + 1;
+ *res_ptr++ = x;
+ if (x != 0)
+ goto fin;
+ }
+
+ return 1;
+ }
+
+ fin:
+ if (res_ptr != s1_ptr)
+ {
+ mp_size_t i;
+ for (i = 0; i < s1_size - 1; i++)
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+_EXTERN_INLINE mp_limb_t
+#if defined (__STDC__) || defined (__cplusplus)
+mpn_add (register mp_ptr res_ptr,
+ register mp_srcptr s1_ptr,
+ register mp_size_t s1_size,
+ register mp_srcptr s2_ptr,
+ register mp_size_t s2_size)
+#else
+mpn_add (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_size_t s1_size;
+ register mp_srcptr s2_ptr;
+ register mp_size_t s2_size;
+#endif
+{
+ mp_limb_t cy_limb = 0;
+
+ if (s2_size != 0)
+ cy_limb = mpn_add_n (res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if (s1_size - s2_size != 0)
+ cy_limb = mpn_add_1 (res_ptr + s2_size,
+ s1_ptr + s2_size,
+ s1_size - s2_size,
+ cy_limb);
+ return cy_limb;
+}
+
+_EXTERN_INLINE mp_limb_t
+#if defined (__STDC__) || defined (__cplusplus)
+mpn_sub_1 (register mp_ptr res_ptr,
+ register mp_srcptr s1_ptr,
+ register mp_size_t s1_size,
+ register mp_limb_t s2_limb)
+#else
+mpn_sub_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+#endif
+{
+ register mp_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x - s2_limb;
+ *res_ptr++ = s2_limb;
+ if (s2_limb > x)
+ {
+ while (--s1_size != 0)
+ {
+ x = *s1_ptr++;
+ *res_ptr++ = x - 1;
+ if (x != 0)
+ goto fin;
+ }
+
+ return 1;
+ }
+
+ fin:
+ if (res_ptr != s1_ptr)
+ {
+ mp_size_t i;
+ for (i = 0; i < s1_size - 1; i++)
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+_EXTERN_INLINE mp_limb_t
+#if defined (__STDC__) || defined (__cplusplus)
+mpn_sub (register mp_ptr res_ptr,
+ register mp_srcptr s1_ptr,
+ register mp_size_t s1_size,
+ register mp_srcptr s2_ptr,
+ register mp_size_t s2_size)
+#else
+mpn_sub (res_ptr, s1_ptr, s1_size, s2_ptr, s2_size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_size_t s1_size;
+ register mp_srcptr s2_ptr;
+ register mp_size_t s2_size;
+#endif
+{
+ mp_limb_t cy_limb = 0;
+
+ if (s2_size != 0)
+ cy_limb = mpn_sub_n (res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if (s1_size - s2_size != 0)
+ cy_limb = mpn_sub_1 (res_ptr + s2_size,
+ s1_ptr + s2_size,
+ s1_size - s2_size,
+ cy_limb);
+ return cy_limb;
+}
+#endif /* __GNUC__ */
+
+/* Allow faster testing for negative, zero, and positive. */
+#define mpz_sgn(Z) ((Z)->_mp_size < 0 ? -1 : (Z)->_mp_size > 0)
+#define mpf_sgn(F) ((F)->_mp_size < 0 ? -1 : (F)->_mp_size > 0)
+#define mpq_sgn(Q) ((Q)->_mp_num._mp_size < 0 ? -1 : (Q)->_mp_num._mp_size > 0)
+
+/* Allow direct user access to numerator and denominator of a mpq_t object. */
+#define mpq_numref(Q) (&((Q)->_mp_num))
+#define mpq_denref(Q) (&((Q)->_mp_den))
+
+/* When using GCC, optimize certain common comparisons. */
+#if defined (__GNUC__)
+#define mpz_cmp_ui(Z,UI) \
+ (__builtin_constant_p (UI) && (UI) == 0 \
+ ? mpz_sgn (Z) : mpz_cmp_ui (Z,UI))
+#define mpz_cmp_si(Z,UI) \
+ (__builtin_constant_p (UI) && (UI) == 0 ? mpz_sgn (Z) \
+ : __builtin_constant_p (UI) && (UI) > 0 ? mpz_cmp_ui (Z,UI) \
+ : mpz_cmp_si (Z,UI))
+#define mpq_cmp_ui(Q,NUI,DUI) \
+ (__builtin_constant_p (NUI) && (NUI) == 0 \
+ ? mpq_sgn (Q) : mpq_cmp_ui (Q,NUI,DUI))
+#endif
+
+#define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize)
+#if 0
+#define mpn_divmod_1(qp,np,nsize,dlimb) mpn_divrem_1 (qp,0,np,nsize,dlimb)
+#endif
+
+/* Compatibility with GMP 1. */
+#define mpz_mdiv mpz_fdiv_q
+#define mpz_mdivmod mpz_fdiv_qr
+#define mpz_mmod mpz_fdiv_r
+#define mpz_mdiv_ui mpz_fdiv_q_ui
+#define mpz_mdivmod_ui(q,r,n,d) \
+ ((r == 0) ? mpz_fdiv_q_ui (q,n,d) : mpz_fdiv_qr_ui (q,r,n,d))
+#define mpz_mmod_ui(r,n,d) \
+ ((r == 0) ? mpz_fdiv_ui (n,d) : mpz_fdiv_r_ui (r,n,d))
+
+/* Useful synonyms, but not quite compatible with GMP 1. */
+#define mpz_div mpz_fdiv_q
+#define mpz_divmod mpz_fdiv_qr
+#define mpz_div_ui mpz_fdiv_q_ui
+#define mpz_divmod_ui mpz_fdiv_qr_ui
+#define mpz_mod_ui mpz_fdiv_r_ui
+#define mpz_div_2exp mpz_fdiv_q_2exp
+#define mpz_mod_2exp mpz_fdiv_r_2exp
+
+#define __GNU_MP_VERSION 2
+#define __GNU_MP_VERSION_MINOR 0
+#define __GMP_H__
+#endif /* __GMP_H__ */
diff --git a/gnu/lib/libgmp/gmp.info-1 b/gnu/lib/libgmp/gmp.info-1
new file mode 100644
index 0000000..4ea9373
--- /dev/null
+++ b/gnu/lib/libgmp/gmp.info-1
@@ -0,0 +1,1283 @@
+This is Info file gmp.info, produced by Makeinfo-1.64 from the input
+file gmp.texi.
+
+START-INFO-DIR-ENTRY
+* gmp: (gmp.info). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+ This file documents GNU MP, a library for arbitrary-precision
+arithmetic.
+
+ Copyright (C) 1991, 1993, 1994, 1995, 1996 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 Foundation.
+
+
+File: gmp.info, Node: Top, Next: Copying, Prev: (dir), Up: (dir)
+
+GNU MP
+******
+
+ This manual documents how to install and use the GNU multiple
+precision arithmetic library, version 2.0.2.
+
+* Menu:
+
+* Copying:: GMP Copying Conditions (LGPL).
+* Introduction to MP:: Brief introduction to GNU MP.
+* Installing MP:: How to configure and compile the MP library.
+* MP Basics:: What every MP user should now.
+* Reporting Bugs:: How to usefully report bugs.
+* Integer Functions:: Functions for arithmetic on signed integers.
+* Rational Number Functions:: Functions for arithmetic on rational numbers.
+* Floating-point Functions:: Functions for arithmetic on floats.
+* Low-level Functions:: Fast functions for natural numbers.
+* BSD Compatible Functions:: All functions found in BSD MP.
+* Custom Allocation:: How to customize the internal allocation.
+
+* Contributors::
+* References::
+* Concept Index::
+* Function Index::
+
+
+File: gmp.info, Node: Copying, Next: Introduction to MP, Prev: Top, Up: Top
+
+GNU MP Copying Conditions
+*************************
+
+ This library is "free"; this means that everyone is free to use it
+and free to redistribute it on a free basis. The library is not in the
+public domain; it is copyrighted and there are restrictions on its
+distribution, but these restrictions are designed to permit everything
+that a good cooperating citizen would want to do. What is not allowed
+is to try to prevent others from further sharing any version of this
+library that they might get from you.
+
+ Specifically, we want to make sure that you have the right to give
+away copies of the library, that you receive source code or else can
+get it if you want it, that you can change this library or use pieces
+of it in new free programs, and that you know you can do these things.
+
+ To make sure that everyone has such rights, we have to forbid you to
+deprive anyone else of these rights. For example, if you distribute
+copies of the GNU MP library, 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 tell them their rights.
+
+ Also, for our own protection, we must make certain that everyone
+finds out that there is no warranty for the GNU MP library. If it is
+modified by someone else and passed on, we want their recipients to
+know that what they have is not what we distributed, so that any
+problems introduced by others will not reflect on our reputation.
+
+ The precise conditions of the license for the GNU MP library are
+found in the Library General Public License that accompany the source
+code.
+
+
+File: gmp.info, Node: Introduction to MP, Next: Installing MP, Prev: Copying, Up: Top
+
+Introduction to GNU MP
+**********************
+
+ GNU MP is a portable library written in C for arbitrary precision
+arithmetic on integers, rational numbers, and floating-point numbers.
+It aims to provide the fastest possible arithmetic for all applications
+that need higher precision than is directly supported by the basic C
+types.
+
+ Many applications use just a few hundred bits of precision; but some
+applications may need thousands or even millions of bits. MP is
+designed to give good performance for both, by choosing algorithms
+based on the sizes of the operands, and by carefully keeping the
+overhead at a minimum.
+
+ The speed of MP is achieved by using fullwords as the basic
+arithmetic type, by using sophisticated algorithms, by including
+carefully optimized assembly code for the most common inner loops for
+many different CPUs, and by a general emphasis on speed (as opposed to
+simplicity or elegance).
+
+ There is carefully optimized assembly code for these CPUs: DEC
+Alpha, Amd 29000, HPPA 1.0 and 1.1, Intel Pentium and generic x86,
+Intel i960, Motorola MC68000, MC68020, MC88100, and MC88110,
+Motorola/IBM PowerPC, National NS32000, IBM POWER, MIPS R3000, R4000,
+SPARCv7, SuperSPARC, generic SPARCv8, and DEC VAX. Some optimizations
+also for ARM, Clipper, IBM ROMP (RT), and Pyramid AP/XP.
+
+ This version of MP is released under a more liberal license than
+previous versions. It is now permitted to link MP to non-free
+programs, as long as MP source code is provided when distributing the
+non-free program.
+
+How to use this Manual
+======================
+
+ Everyone should read *Note MP Basics::. If you need to install the
+library yourself, you need to read *Note Installing MP::, too.
+
+ The rest of the manual can be used for later reference, although it
+is probably a good idea to glance through it.
+
+
+File: gmp.info, Node: Installing MP, Next: MP Basics, Prev: Introduction to MP, Up: Top
+
+Installing MP
+*************
+
+ To build MP, you first have to configure it for your CPU and
+operating system. You need a C compiler, preferably GCC, but any
+reasonable compiler should work. And you need a standard Unix `make'
+program, plus some other standard Unix utility programs.
+
+ (If you're on an MS-DOS machine, your can build MP using `make.bat'.
+It requires that djgpp is installed. It does not require
+configuration, nor is `make' needed; `make.bat' both configures and
+builds the library.)
+
+ Here are the steps needed to install the library on Unix systems:
+
+ 1. In most cases, `./configure --target=cpu-vendor-os', should work
+ both for native and cross-compilation. If you get error messages,
+ your machine might not be supported.
+
+ If you want to compile in a separate object directory, cd to that
+ directory, and prefix the configure command with the path to the
+ MP source directory. Not all `make' programs have the necessary
+ features to support this. In particular, SunOS and Slowaris
+ `make' have bugs that makes them unable to build from a separate
+ object directory. Use GNU `make' instead.
+
+ In addition to the standard cpu-vendor-os tuples, MP recognizes
+ sparc8 and supersparc as valid CPU names. Specifying these CPU
+ names for relevant systems will improve performance significantly.
+
+ In general, if you want a library that runs as fast as possible,
+ you should make sure you configure MP for the exact CPU type your
+ system uses.
+
+ If you have `gcc' in your `PATH', it will be used by default. To
+ override this, pass `-with-gcc=no' to `configure'.
+
+ 2. `make'
+
+ This will compile MP, and create a library archive file `libgmp.a'
+ in the working directory.
+
+ 3. `make check'
+
+ This will make sure MP was built correctly. If you get error
+ messages, please report this to `bug-gmp@prep.ai.mit.edu'. (*Note
+ Reporting Bugs::, for information on what to include in useful bug
+ reports.)
+
+ 4. `make install'
+
+ This will copy the file `gmp.h' and `libgmp.a', as well as the info
+ files, to `/usr/local' (or if you passed the `--prefix' option to
+ `configure', to the directory given as argument to `--prefix').
+
+If you wish to build and install the BSD MP compatible functions, use
+`make libmp.a' and `make install-bsdmp'.
+
+ There are some other useful make targets:
+
+ * `doc'
+
+ Create a DVI version of the manual, in `gmp.dvi' and a set of info
+ files, in `gmp.info', `gmp.info-1', `gmp.info-2', etc.
+
+ * `ps'
+
+ Create a Postscript version of the manual, in `gmp.ps'.
+
+ * `html'
+
+ Create a HTML version of the manual, in `gmp.html'.
+
+ * `clean'
+
+ Delete all object files and archive files, but not the
+ configuration files.
+
+ * `distclean'
+
+ Delete all files not included in the distribution.
+
+ * `uninstall'
+
+ Delete all files copied by `make install'.
+
+Known Build Problems
+====================
+
+ GCC 2.7.2 (as well as 2.6.3) for the RS/6000 and PowerPC can not be
+used to compile MP, due to a bug in GCC. If you want to use GCC for
+these machines, you need to apply the patch below to GCC, or use a
+later version of the compiler.
+
+ If you are on a Sequent Symmetry, use the GNU assembler instead of
+the system's assembler, since the latter has serious bugs.
+
+ The system compiler on NeXT is a massacred and old gcc, even if the
+compiler calls itself `cc'. This compiler cannot be used to build MP.
+You need to get a real gcc, and install that before you compile MP.
+(NeXT might have fixed this in newer releases of their system.)
+
+ The system C compiler under SunOS 4 has a bug that makes it
+miscompile mpq/get_d.c. This will make `make check' fail.
+
+ Please report other problems to `bug-gmp@prep.ai.mit.edu'. *Note
+Reporting Bugs::.
+
+ Patch to apply to GCC 2.6.3 and 2.7.2:
+
+ *** config/rs6000/rs6000.md Sun Feb 11 08:22:11 1996
+ --- config/rs6000/rs6000.md.new Sun Feb 18 03:33:37 1996
+ ***************
+ *** 920,926 ****
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+ ! "nor. %0,%2,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
+ --- 920,926 ----
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+ ! "nor. %0,%1,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
+
+
+File: gmp.info, Node: MP Basics, Next: Reporting Bugs, Prev: Installing MP, Up: Top
+
+MP Basics
+*********
+
+ All declarations needed to use MP are collected in the include file
+`gmp.h'. It is designed to work with both C and C++ compilers.
+
+Nomenclature and Types
+======================
+
+In this manual, "integer" usually means a multiple precision integer, as
+defined by the MP library. The C data type for such integers is
+`mpz_t'. Here are some examples of how to declare such integers:
+
+ mpz_t sum;
+
+ struct foo { mpz_t x, y; };
+
+ mpz_t vec[20];
+
+"Rational number" means a multiple precision fraction. The C data type
+for these fractions is `mpq_t'. For example:
+
+ mpq_t quotient;
+
+"Floating point number" or "Float" for short, is an arbitrary precision
+mantissa with an limited precision exponent. The C data type for such
+objects is `mpf_t'.
+
+A "limb" means the part of a multi-precision number that fits in a
+single word. (We chose this word because a limb of the human body is
+analogous to a digit, only larger, and containing several digits.)
+Normally a limb contains 32 or 64 bits. The C data type for a limb is
+`mp_limb_t'.
+
+Function Classes
+================
+
+ There are six classes of functions in the MP library:
+
+ 1. Functions for signed integer arithmetic, with names beginning with
+ `mpz_'. The associated type is `mpz_t'. There are about 100
+ functions in this class.
+
+ 2. Functions for rational number arithmetic, with names beginning with
+ `mpq_'. The associated type is `mpq_t'. There are about 20
+ functions in this class, but the functions in the previous class
+ can be used for performing arithmetic on the numerator and
+ denominator separately.
+
+ 3. Functions for floating-point arithmetic, with names beginning with
+ `mpf_'. The associated type is `mpf_t'. There are about 50
+ functions is this class.
+
+ 4. Functions compatible with Berkeley MP, such as `itom', `madd', and
+ `mult'. The associated type is `MINT'.
+
+ 5. Fast low-level functions that operate on natural numbers. These
+ are used by the functions in the preceding groups, and you can
+ also call them directly from very time-critical user programs.
+ These functions' names begin with `mpn_'. There are about 30
+ (hard-to-use) functions in this class.
+
+ The associated type is array of `mp_limb_t'.
+
+ 6. Miscellaneous functions. Functions for setting up custom
+ allocation.
+
+MP Variable Conventions
+=======================
+
+ As a general rule, all MP functions expect output arguments before
+input arguments. This notation is based on an analogy with the
+assignment operator. (The BSD MP compatibility functions disobey this
+rule, having the output argument(s) last.)
+
+ MP allows you to use the same variable for both input and output in
+the same expression. For example, the main function for integer
+multiplication, `mpz_mul', can be used like this: `mpz_mul (x, x, x)'.
+This computes the square of X and puts the result back in X.
+
+ Before you can assign to an MP variable, you need to initialize it
+by calling one of the special initialization functions. When you're
+done with a variable, you need to clear it out, using one of the
+functions for that purpose. Which function to use depends on the type
+of variable. See the chapters on integer functions, rational number
+functions, and floating-point functions for details.
+
+ A variable should only be initialized once, or at least cleared out
+between each initialization. After a variable has been initialized, it
+may be assigned to any number of times.
+
+ For efficiency reasons, avoid to initialize and clear out a variable
+in loops. Instead, initialize it before entering the loop, and clear
+it out after the loop has exited.
+
+ You don't need to be concerned about allocating additional space for
+MP variables. All functions in MP automatically allocate additional
+space when a variable does not already have enough space. They do not,
+however, reduce the space when a smaller number is stored in the
+object. Most of the time, this policy is best, since it avoids
+frequent re-allocation.
+
+Useful Macros and Constants
+===========================
+
+ - Global Constant: const int mp_bits_per_limb
+ The number of bits per limb.
+
+ - Macro: __GNU_MP_VERSION
+ - Macro: __GNU_MP_VERSION_MINOR
+ The major and minor MP version, respectively, as integers.
+
+Compatibility with Version 1.x
+==============================
+
+ This version of MP is upward compatible with previous versions of
+MP, with a few exceptions.
+
+ 1. Integer division functions round the result differently. The old
+ functions (`mpz_div', `mpz_divmod', `mpz_mdiv', `mpz_mdivmod',
+ etc) now all use floor rounding (i.e., they round the quotient to
+ -infinity). There are a lot of new functions for integer
+ division, giving the user better control over the rounding.
+
+ 2. The function `mpz_mod' now compute the true *mod* function.
+
+ 3. The functions `mpz_powm' and `mpz_powm_ui' now use *mod* for
+ reduction.
+
+ 4. The assignment functions for rational numbers do no longer
+ canonicalize their results. In the case a non-canonical result
+ could arise from an assignment, the user need to insert an
+ explicit call to `mpq_canonicalize'. This change was made for
+ efficiency.
+
+ 5. Output generated by `mpz_out_raw' in this release cannot be read
+ by `mpz_inp_raw' in previous releases. This change was made for
+ making the file format truly portable between machines with
+ different word sizes.
+
+ 6. Several `mpn' functions have changed. But they were intentionally
+ undocumented in previous releases.
+
+ 7. The functions `mpz_cmp_ui', `mpz_cmp_si', and `mpq_cmp_ui' are now
+ implementated as macros, and thereby sometimes evaluate their
+ arguments multiple times.
+
+ 8. The functions `mpz_pow_ui' and `mpz_ui_pow_ui' now yield 1 for
+ 0^0. (In version 1, they yielded 0.)
+
+
+Getting the Latest Version of MP
+================================
+
+ The latest version of the MP library is available by anonymous ftp
+from from `prep.ai.mit.edu'. The file name is
+`/pub/gnu/gmp-M.N.tar.gz'. Many sites around the world mirror `prep';
+please use a mirror site near you.
+
+
+File: gmp.info, Node: Reporting Bugs, Next: Integer Functions, Prev: MP Basics, Up: Top
+
+Reporting Bugs
+**************
+
+ If you think you have found a bug in the MP library, please
+investigate it and report it. We have made this library available to
+you, and it is not to ask too much from you, to ask you to report the
+bugs that you find.
+
+ There are a few things you should think about when you put your bug
+report together.
+
+ You have to send us a test case that makes it possible for us to
+reproduce the bug. Include instructions on how to run the test case.
+
+ You also have to explain what is wrong; if you get a crash, or if
+the results printed are incorrect and in that case, in what way.
+
+ It is not uncommon that an observed problem is actually due to a bug
+in the compiler used when building MP; the MP code tends to explore
+interesting corners in compilers. Therefore, please include compiler
+version information in your bug report. This can be extracted using
+`what `which cc`', or, if you're using gcc, `gcc -v'. Also, include
+the output from `uname -a'.
+
+ If your bug report is good, we will do our best to help you to get a
+corrected version of the library; if the bug report is poor, we won't
+do anything about it (aside of chiding you to send better bug reports).
+
+ Send your bug report to: `bug-gmp@prep.ai.mit.edu'.
+
+ If you think something in this manual is unclear, or downright
+incorrect, or if the language needs to be improved, please send a note
+to the same address.
+
+
+File: gmp.info, Node: Integer Functions, Next: Rational Number Functions, Prev: Reporting Bugs, Up: Top
+
+Integer Functions
+*****************
+
+ This chapter describes the MP functions for performing integer
+arithmetic. These functions start with the prefix `mpz_'.
+
+ Arbitrary precision integers are stored in objects of type `mpz_t'.
+
+* Menu:
+
+* Initializing Integers::
+* Assigning Integers::
+* Simultaneous Integer Init & Assign::
+* Converting Integers::
+* Integer Arithmetic::
+* Comparison Functions::
+* Integer Logic and Bit Fiddling::
+* I/O of Integers::
+* Miscellaneous Integer Functions::
+
+
+File: gmp.info, Node: Initializing Integers, Next: Assigning Integers, Up: Integer Functions
+
+Initialization and Assignment Functions
+=======================================
+
+ The functions for integer arithmetic assume that all integer objects
+are initialized. You do that by calling the function `mpz_init'.
+
+ - Function: void mpz_init (mpz_t INTEGER)
+ Initialize INTEGER with limb space and set the initial numeric
+ value to 0. Each variable should normally only be initialized
+ once, or at least cleared out (using `mpz_clear') between each
+ initialization.
+
+ Here is an example of using `mpz_init':
+
+ {
+ mpz_t integ;
+ mpz_init (integ);
+ ...
+ mpz_add (integ, ...);
+ ...
+ mpz_sub (integ, ...);
+
+ /* Unless the program is about to exit, do ... */
+ mpz_clear (integ);
+ }
+
+As you can see, you can store new values any number of times, once an
+object is initialized.
+
+ - Function: void mpz_clear (mpz_t INTEGER)
+ Free the limb space occupied by INTEGER. Make sure to call this
+ function for all `mpz_t' variables when you are done with them.
+
+ - Function: void * _mpz_realloc (mpz_t INTEGER, mp_size_t NEW_ALLOC)
+ Change the limb space allocation to NEW_ALLOC limbs. This
+ function is not normally called from user code, but it can be used
+ to give memory back to the heap, or to increase the space of a
+ variable to avoid repeated automatic re-allocation.
+
+ - Function: void mpz_array_init (mpz_t INTEGER_ARRAY[], size_t
+ ARRAY_SIZE, mp_size_t FIXED_NUM_BITS)
+ Allocate *fixed* limb space for all ARRAY_SIZE integers in
+ INTEGER_ARRAY. The fixed allocation for each integer in the array
+ is enough to store FIXED_NUM_BITS. If the fixed space will be
+ insufficient for storing the result of a subsequent calculation,
+ the result is unpredictable.
+
+ This function is useful for decreasing the working set for some
+ algorithms that use large integer arrays.
+
+ There is no way to de-allocate the storage allocated by this
+ function. Don't call `mpz_clear'!
+
+
+File: gmp.info, Node: Assigning Integers, Next: Simultaneous Integer Init & Assign, Prev: Initializing Integers, Up: Integer Functions
+
+Assignment Functions
+--------------------
+
+ These functions assign new values to already initialized integers
+(*note Initializing Integers::.).
+
+ - Function: void mpz_set (mpz_t ROP, mpz_t OP)
+ - Function: void mpz_set_ui (mpz_t ROP, unsigned long int OP)
+ - Function: void mpz_set_si (mpz_t ROP, signed long int OP)
+ - Function: void mpz_set_d (mpz_t ROP, double OP)
+ - Function: void mpz_set_q (mpz_t ROP, mpq_t OP)
+ - Function: void mpz_set_f (mpz_t ROP, mpf_t OP)
+ Set the value of ROP from OP.
+
+ - Function: int mpz_set_str (mpz_t ROP, char *STR, int BASE)
+ Set the value of ROP from STR, a '\0'-terminated C string in base
+ BASE. White space is allowed in the string, and is simply
+ ignored. The base may vary from 2 to 36. If BASE is 0, the
+ actual base is determined from the leading characters: if the
+ first two characters are `0x' or `0X', hexadecimal is assumed,
+ otherwise if the first character is `0', octal is assumed,
+ otherwise decimal is assumed.
+
+ This function returns 0 if the entire string up to the '\0' is a
+ valid number in base BASE. Otherwise it returns -1.
+
+
+File: gmp.info, Node: Simultaneous Integer Init & Assign, Next: Converting Integers, Prev: Assigning Integers, Up: Integer Functions
+
+Combined Initialization and Assignment Functions
+------------------------------------------------
+
+ For convenience, MP provides a parallel series of initialize-and-set
+functions which initialize the output and then store the value there.
+These functions' names have the form `mpz_init_set...'
+
+ Here is an example of using one:
+
+ {
+ mpz_t pie;
+ mpz_init_set_str (pie, "3141592653589793238462643383279502884", 10);
+ ...
+ mpz_sub (pie, ...);
+ ...
+ mpz_clear (pie);
+ }
+
+Once the integer has been initialized by any of the `mpz_init_set...'
+functions, it can be used as the source or destination operand for the
+ordinary integer functions. Don't use an initialize-and-set function
+on a variable already initialized!
+
+ - Function: void mpz_init_set (mpz_t ROP, mpz_t OP)
+ - Function: void mpz_init_set_ui (mpz_t ROP, unsigned long int OP)
+ - Function: void mpz_init_set_si (mpz_t ROP, signed long int OP)
+ - Function: void mpz_init_set_d (mpz_t ROP, double OP)
+ Initialize ROP with limb space and set the initial numeric value
+ from OP.
+
+ - Function: int mpz_init_set_str (mpz_t ROP, char *STR, int BASE)
+ Initialize ROP and set its value like `mpz_set_str' (see its
+ documentation above for details).
+
+ If the string is a correct base BASE number, the function returns
+ 0; if an error occurs it returns -1. ROP is initialized even if
+ an error occurs. (I.e., you have to call `mpz_clear' for it.)
+
+
+File: gmp.info, Node: Converting Integers, Next: Integer Arithmetic, Prev: Simultaneous Integer Init & Assign, Up: Integer Functions
+
+Conversion Functions
+====================
+
+ This section describes functions for converting arbitrary precision
+integers to standard C types. Functions for converting *to* arbitrary
+precision integers are described in *Note Assigning Integers:: and
+*Note I/O of Integers::.
+
+ - Function: unsigned long int mpz_get_ui (mpz_t OP)
+ Return the least significant part from OP. This function combined
+ with
+ `mpz_tdiv_q_2exp(..., OP, CHAR_BIT*sizeof(unsigned long int))' can
+ be used to extract the limbs of an integer.
+
+ - Function: signed long int mpz_get_si (mpz_t OP)
+ If OP fits into a `signed long int' return the value of OP.
+ Otherwise return the least significant part of OP, with the same
+ sign as OP.
+
+ If OP is too large to fit in a `signed long int', the returned
+ result is probably not very useful.
+
+ - Function: double mpz_get_d (mpz_t OP)
+ Convert OP to a double.
+
+ - Function: char * mpz_get_str (char *STR, int BASE, mpz_t OP)
+ Convert OP to a string of digits in base BASE. The base may vary
+ from 2 to 36.
+
+ If STR is NULL, space for the result string is allocated using the
+ default allocation function, and a pointer to the string is
+ returned.
+
+ If STR is not NULL, it should point to a block of storage enough
+ large for the result. To find out the right amount of space to
+ provide for STR, use `mpz_sizeinbase (OP, BASE) + 2'. The two
+ extra bytes are for a possible minus sign, and for the terminating
+ null character.
+
+
+File: gmp.info, Node: Integer Arithmetic, Next: Comparison Functions, Prev: Converting Integers, Up: Integer Functions
+
+Arithmetic Functions
+====================
+
+ - Function: void mpz_add (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_add_ui (mpz_t ROP, mpz_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 + OP2.
+
+ - Function: void mpz_sub (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_sub_ui (mpz_t ROP, mpz_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 - OP2.
+
+ - Function: void mpz_mul (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_mul_ui (mpz_t ROP, mpz_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 times OP2.
+
+ - Function: void mpz_mul_2exp (mpz_t ROP, mpz_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 times 2 raised to OP2. This operation can also be
+ defined as a left shift, OP2 steps.
+
+ - Function: void mpz_neg (mpz_t ROP, mpz_t OP)
+ Set ROP to -OP.
+
+ - Function: void mpz_abs (mpz_t ROP, mpz_t OP)
+ Set ROP to the absolute value of OP.
+
+ - Function: void mpz_fac_ui (mpz_t ROP, unsigned long int OP)
+ Set ROP to OP!, the factorial of OP.
+
+Division functions
+------------------
+
+ Division is undefined if the divisor is zero, and passing a zero
+divisor to the divide or modulo functions, as well passing a zero mod
+argument to the `mpz_powm' and `mpz_powm_ui' functions, will make these
+functions intentionally divide by zero. This gives the user the
+possibility to handle arithmetic exceptions in these functions in the
+same manner as other arithmetic exceptions.
+
+ There are three main groups of division functions:
+ * Functions that truncate the quotient towards 0. The names of these
+ functions start with `mpz_tdiv'. The `t' in the name is short for
+ `truncate'.
+
+ * Functions that round the quotient towards -infinity. The names of
+ these routines start with `mpz_fdiv'. The `f' in the name is
+ short for `floor'.
+
+ * Functions that round the quotient towards +infinity. The names of
+ these routines start with `mpz_cdiv'. The `c' in the name is
+ short for `ceil'.
+
+ For each rounding mode, there are a couple of variants. Here `q'
+means that the quotient is computed, while `r' means that the remainder
+is computed. Functions that compute both the quotient and remainder
+have `qr' in the name.
+
+ - Function: void mpz_tdiv_q (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_tdiv_q_ui (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to [OP1/OP2]. The quotient is truncated towards 0.
+
+ - Function: void mpz_tdiv_r (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_tdiv_r_ui (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to (OP1 - [OP1/OP2] * OP2). Unless the remainder is zero,
+ it has the same sign as the dividend.
+
+ - Function: void mpz_tdiv_qr (mpz_t ROP1, mpz_t ROP2, mpz_t OP1, mpz_t
+ OP2)
+ - Function: void mpz_tdiv_qr_ui (mpz_t ROP1, mpz_t ROP2, mpz_t OP1,
+ unsigned long int OP2)
+ Divide OP1 by OP2 and put the quotient in ROP1 and the remainder
+ in ROP2. The quotient is rounded towards 0. Unless the remainder
+ is zero, it has the same sign as the dividend.
+
+ If ROP1 and ROP2 are the same variable, the results are undefined.
+
+ - Function: void mpz_fdiv_q (mpz_t ROP1, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_fdiv_q_ui (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to OP1/OP2. The quotient is rounded towards -infinity.
+
+ - Function: void mpz_fdiv_r (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: unsigned long int mpz_fdiv_r_ui (mpz_t ROP, mpz_t OP1,
+ unsigned long int OP2)
+ Divide OP1 by OP2 and put the remainder in ROP. Unless the
+ remainder is zero, it has the same sign as the divisor.
+
+ For `mpz_fdiv_r_ui' the remainder is small enough to fit in an
+ `unsigned long int', and is therefore returned.
+
+ - Function: void mpz_fdiv_qr (mpz_t ROP1, mpz_t ROP2, mpz_t OP1, mpz_t
+ OP2)
+ - Function: unsigned long int mpz_fdiv_qr_ui (mpz_t ROP1, mpz_t ROP2,
+ mpz_t OP1, unsigned long int OP2)
+ Divide OP1 by OP2 and put the quotient in ROP1 and the remainder
+ in ROP2. The quotient is rounded towards -infinity. Unless the
+ remainder is zero, it has the same sign as the divisor.
+
+ For `mpz_fdiv_qr_ui' the remainder is small enough to fit in an
+ `unsigned long int', and is therefore returned.
+
+ If ROP1 and ROP2 are the same variable, the results are undefined.
+
+ - Function: unsigned long int mpz_fdiv_ui (mpz_t OP1, unsigned long
+ int OP2)
+ This function is similar to `mpz_fdiv_r_ui', but the remainder is
+ only returned; it is not stored anywhere.
+
+ - Function: void mpz_cdiv_q (mpz_t ROP1, mpz_t OP1, mpz_t OP2)
+ - Function: void mpz_cdiv_q_ui (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to OP1/OP2. The quotient is rounded towards +infinity.
+
+ - Function: void mpz_cdiv_r (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: unsigned long int mpz_cdiv_r_ui (mpz_t ROP, mpz_t OP1,
+ unsigned long int OP2)
+ Divide OP1 by OP2 and put the remainder in ROP. Unless the
+ remainder is zero, it has the opposite sign as the divisor.
+
+ For `mpz_cdiv_r_ui' the negated remainder is small enough to fit
+ in an `unsigned long int', and it is therefore returned.
+
+ - Function: void mpz_cdiv_qr (mpz_t ROP1, mpz_t ROP2, mpz_t OP1, mpz_t
+ OP2)
+ - Function: unsigned long int mpz_cdiv_qr_ui (mpz_t ROP1, mpz_t ROP2,
+ mpz_t OP1, unsigned long int OP2)
+ Divide OP1 by OP2 and put the quotient in ROP1 and the remainder
+ in ROP2. The quotient is rounded towards +infinity. Unless the
+ remainder is zero, it has the opposite sign as the divisor.
+
+ For `mpz_cdiv_qr_ui' the negated remainder is small enough to fit
+ in an `unsigned long int', and it is therefore returned.
+
+ If ROP1 and ROP2 are the same variable, the results are undefined.
+
+ - Function: unsigned long int mpz_cdiv_ui (mpz_t OP1, unsigned long
+ int OP2)
+ Return the negated remainder, similar to `mpz_cdiv_r_ui'. (The
+ difference is that this function doesn't store the remainder
+ anywhere.)
+
+ - Function: void mpz_mod (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ - Function: unsigned long int mpz_mod_ui (mpz_t ROP, mpz_t OP1,
+ unsigned long int OP2)
+ Set ROP to OP1 `mod' OP2. The sign of the divisor is ignored, and
+ the result is always non-negative.
+
+ For `mpz_mod_ui' the remainder is small enough to fit in an
+ `unsigned long int', and is therefore returned.
+
+ - Function: void mpz_divexact (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ Set ROP to OP1/OP2. This function produces correct results only
+ when it is known in advance that OP2 divides OP1.
+
+ Since mpz_divexact is much faster than any of the other routines
+ that produce the quotient (*note References::. Jebelean), it is
+ the best choice for instances in which exact division is known to
+ occur, such as reducing a rational to lowest terms.
+
+ - Function: void mpz_tdiv_q_2exp (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to OP1 divided by 2 raised to OP2. The quotient is
+ rounded towards 0.
+
+ - Function: void mpz_tdiv_r_2exp (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Divide OP1 by (2 raised to OP2) and put the remainder in ROP.
+ Unless it is zero, ROP will have the same sign as OP1.
+
+ - Function: void mpz_fdiv_q_2exp (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Set ROP to OP1 divided by 2 raised to OP2. The quotient is
+ rounded towards -infinity.
+
+ - Function: void mpz_fdiv_r_2exp (mpz_t ROP, mpz_t OP1, unsigned long
+ int OP2)
+ Divide OP1 by (2 raised to OP2) and put the remainder in ROP. The
+ sign of ROP will always be positive.
+
+ This operation can also be defined as masking of the OP2 least
+ significant bits.
+
+Exponentialization Functions
+----------------------------
+
+ - Function: void mpz_powm (mpz_t ROP, mpz_t BASE, mpz_t EXP, mpz_t MOD)
+ - Function: void mpz_powm_ui (mpz_t ROP, mpz_t BASE, unsigned long int
+ EXP, mpz_t MOD)
+ Set ROP to (BASE raised to EXP) `mod' MOD. If EXP is negative,
+ the result is undefined.
+
+ - Function: void mpz_pow_ui (mpz_t ROP, mpz_t BASE, unsigned long int
+ EXP)
+ - Function: void mpz_ui_pow_ui (mpz_t ROP, unsigned long int BASE,
+ unsigned long int EXP)
+ Set ROP to BASE raised to EXP. The case of 0^0 yields 1.
+
+Square Root Functions
+---------------------
+
+ - Function: void mpz_sqrt (mpz_t ROP, mpz_t OP)
+ Set ROP to the truncated integer part of the square root of OP.
+
+ - Function: void mpz_sqrtrem (mpz_t ROP1, mpz_t ROP2, mpz_t OP)
+ Set ROP1 to the truncated integer part of the square root of OP,
+ like `mpz_sqrt'. Set ROP2 to OP-ROP1*ROP1, (i.e., zero if OP is a
+ perfect square).
+
+ If ROP1 and ROP2 are the same variable, the results are undefined.
+
+ - Function: int mpz_perfect_square_p (mpz_t OP)
+ Return non-zero if OP is a perfect square, i.e., if the square
+ root of OP is an integer. Return zero otherwise.
+
+Number Theoretic Functions
+--------------------------
+
+ - Function: int mpz_probab_prime_p (mpz_t OP, int REPS)
+ If this function returns 0, OP is definitely not prime. If it
+ returns 1, then OP is `probably' prime. The probability of a
+ false positive is (1/4)**REPS. A reasonable value of reps is 25.
+
+ An implementation of the probabilistic primality test found in
+ Seminumerical Algorithms (*note References::. Knuth).
+
+ - Function: void mpz_gcd (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ Set ROP to the greatest common divisor of OP1 and OP2.
+
+ - Function: unsigned long int mpz_gcd_ui (mpz_t ROP, mpz_t OP1,
+ unsigned long int OP2)
+ Compute the greatest common divisor of OP1 and OP2. If ROP is not
+ NULL, store the result there.
+
+ If the result is small enough to fit in an `unsigned long int', it
+ is returned. If the result does not fit, 0 is returned, and the
+ result is equal to the argument OP1. Note that the result will
+ always fit if OP2 is non-zero.
+
+ - Function: void mpz_gcdext (mpz_t G, mpz_t S, mpz_t T, mpz_t A, mpz_t
+ B)
+ Compute G, S, and T, such that AS + BT = G = `gcd' (A, B). If T is
+ NULL, that argument is not computed.
+
+ - Function: int mpz_invert (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ Compute the inverse of OP1 modulo OP2 and put the result in ROP.
+ Return non-zero if an inverse exist, zero otherwise. When the
+ function returns zero, do not assume anything about the value in
+ ROP.
+
+ - Function: int mpz_jacobi (mpz_t OP1, mpz_t OP2)
+ - Function: int mpz_legendre (mpz_t OP1, mpz_t OP2)
+ Compute the Jacobi and Legendre symbols, respectively.
+
+
+File: gmp.info, Node: Comparison Functions, Next: Integer Logic and Bit Fiddling, Prev: Integer Arithmetic, Up: Integer Functions
+
+Comparison Functions
+====================
+
+ - Function: int mpz_cmp (mpz_t OP1, mpz_t OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ - Macro: int mpz_cmp_ui (mpz_t OP1, unsigned long int OP2)
+ - Macro: int mpz_cmp_si (mpz_t OP1, signed long int OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ These functions are actually implemented as macros. They evaluate
+ their arguments multiple times.
+
+ - Macro: int mpz_sgn (mpz_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates its
+ arguments multiple times.
+
+
+File: gmp.info, Node: Integer Logic and Bit Fiddling, Next: I/O of Integers, Prev: Comparison Functions, Up: Integer Functions
+
+Logical and Bit Manipulation Functions
+======================================
+
+ These functions behave as if two's complement arithmetic were used
+(although sign-magnitude is used by the actual implementation).
+
+ - Function: void mpz_and (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ Set ROP to OP1 logical-and OP2.
+
+ - Function: void mpz_ior (mpz_t ROP, mpz_t OP1, mpz_t OP2)
+ Set ROP to OP1 inclusive-or OP2.
+
+ - Function: void mpz_com (mpz_t ROP, mpz_t OP)
+ Set ROP to the one's complement of OP.
+
+ - Function: unsigned long int mpz_popcount (mpz_t OP)
+ For non-negative numbers, return the population count of OP. For
+ negative numbers, return the largest possible value (MAX_ULONG).
+
+ - Function: unsigned long int mpz_hamdist (mpz_t OP1, mpz_t OP2)
+ If OP1 and OP2 are both non-negative, return the hamming distance
+ between the two operands. Otherwise, return the largest possible
+ value (MAX_ULONG).
+
+ It is possible to extend this function to return a useful value
+ when the operands are both negative, but the current
+ implementation returns MAX_ULONG in this case. *Do not depend on
+ this behavior, since it will change in future versions of the
+ library.*
+
+ - Function: unsigned long int mpz_scan0 (mpz_t OP, unsigned long int
+ STARTING_BIT)
+ Scan OP, starting with bit STARTING_BIT, towards more significant
+ bits, until the first clear bit is found. Return the index of the
+ found bit.
+
+ - Function: unsigned long int mpz_scan1 (mpz_t OP, unsigned long int
+ STARTING_BIT)
+ Scan OP, starting with bit STARTING_BIT, towards more significant
+ bits, until the first set bit is found. Return the index of the
+ found bit.
+
+ - Function: void mpz_setbit (mpz_t ROP, unsigned long int BIT_INDEX)
+ Set bit BIT_INDEX in OP1.
+
+ - Function: void mpz_clrbit (mpz_t ROP, unsigned long int BIT_INDEX)
+ Clear bit BIT_INDEX in OP1.
+
+
+File: gmp.info, Node: I/O of Integers, Next: Miscellaneous Integer Functions, Prev: Integer Logic and Bit Fiddling, Up: Integer Functions
+
+Input and Output Functions
+==========================
+
+ Functions that perform input from a stdio stream, and functions that
+output to a stdio stream. Passing a NULL pointer for a STREAM argument
+to any of these functions will make them read from `stdin' and write to
+`stdout', respectively.
+
+ When using any of these functions, it is a good idea to include
+`stdio.h' before `gmp.h', since that will allow `gmp.h' to define
+prototypes for these functions.
+
+ - Function: size_t mpz_out_str (FILE *STREAM, int BASE, mpz_t OP)
+ Output OP on stdio stream STREAM, as a string of digits in base
+ BASE. The base may vary from 2 to 36.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ - Function: size_t mpz_inp_str (mpz_t ROP, FILE *STREAM, int BASE)
+ Input a possibly white-space preceded string in base BASE from
+ stdio stream STREAM, and put the read integer in ROP. The base
+ may vary from 2 to 36. If BASE is 0, the actual base is
+ determined from the leading characters: if the first two
+ characters are `0x' or `0X', hexadecimal is assumed, otherwise if
+ the first character is `0', octal is assumed, otherwise decimal is
+ assumed.
+
+ Return the number of bytes read, or if an error occurred, return 0.
+
+ - Function: size_t mpz_out_raw (FILE *STREAM, mpz_t OP)
+ Output OP on stdio stream STREAM, in raw binary format. The
+ integer is written in a portable format, with 4 bytes of size
+ information, and that many bytes of limbs. Both the size and the
+ limbs are written in decreasing significance order (i.e., in
+ big-endian).
+
+ The output can be read with `mpz_inp_raw'.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ The output of this can not be read by `mpz_inp_raw' from GMP 1,
+ because of changes necessary for compatibility between 32-bit and
+ 64-bit machines.
+
+ - Function: size_t mpz_inp_raw (mpz_t ROP, FILE *STREAM)
+ Input from stdio stream STREAM in the format written by
+ `mpz_out_raw', and put the result in ROP. Return the number of
+ bytes read, or if an error occurred, return 0.
+
+ This routine can read the output from `mpz_out_raw' also from GMP
+ 1, in spite of changes necessary for compatibility between 32-bit
+ and 64-bit machines.
+
+
+File: gmp.info, Node: Miscellaneous Integer Functions, Prev: I/O of Integers, Up: Integer Functions
+
+Miscellaneous Functions
+=======================
+
+ - Function: void mpz_random (mpz_t ROP, mp_size_t MAX_SIZE)
+ Generate a random integer of at most MAX_SIZE limbs. The generated
+ random number doesn't satisfy any particular requirements of
+ randomness. Negative random numbers are generated when MAX_SIZE
+ is negative.
+
+ - Function: void mpz_random2 (mpz_t ROP, mp_size_t MAX_SIZE)
+ Generate a random integer of at most MAX_SIZE limbs, with long
+ strings of zeros and ones in the binary representation. Useful
+ for testing functions and algorithms, since this kind of random
+ numbers have proven to be more likely to trigger corner-case bugs.
+ Negative random numbers are generated when MAX_SIZE is negative.
+
+ - Function: size_t mpz_size (mpz_t OP)
+ Return the size of OP measured in number of limbs. If OP is zero,
+ the returned value will be zero.
+
+ *This function is obsolete. It will disappear from future MP
+ releases.*
+
+ - Function: size_t mpz_sizeinbase (mpz_t OP, int BASE)
+ Return the size of OP measured in number of digits in base BASE.
+ The base may vary from 2 to 36. The returned value will be exact
+ or 1 too big. If BASE is a power of 2, the returned value will
+ always be exact.
+
+ This function is useful in order to allocate the right amount of
+ space before converting OP to a string. The right amount of
+ allocation is normally two more than the value returned by
+ `mpz_sizeinbase' (one extra for a minus sign and one for the
+ terminating '\0').
+
+
+File: gmp.info, Node: Rational Number Functions, Next: Floating-point Functions, Prev: Integer Functions, Up: Top
+
+Rational Number Functions
+*************************
+
+ This chapter describes the MP functions for performing arithmetic on
+rational numbers. These functions start with the prefix `mpq_'.
+
+ Rational numbers are stored in objects of type `mpq_t'.
+
+ All rational arithmetic functions assume operands have a canonical
+form, and canonicalize their result. The canonical from means that the
+denominator and the numerator have no common factors, and that the
+denominator is positive. Zero has the unique representation 0/1.
+
+ Pure assignment functions do not canonicalize the assigned variable.
+It is the responsibility of the user to canonicalize the assigned
+variable before any arithmetic operations are performed on that
+variable. *Note that this is an incompatible change from version 1 of
+the library.*
+
+ - Function: void mpq_canonicalize (mpq_t OP)
+ Remove any factors that are common to the numerator and
+ denominator of OP, and make the denominator positive.
+
+* Menu:
+
+* Initializing Rationals::
+* Assigning Rationals::
+* Simultaneous Integer Init & Assign::
+* Comparing Rationals::
+* Applying Integer Functions::
+* Miscellaneous Rational Functions::
+
+
+File: gmp.info, Node: Initializing Rationals, Next: Assigning Rationals, Prev: Rational Number Functions, Up: Rational Number Functions
+
+Initialization and Assignment Functions
+=======================================
+
+ - Function: void mpq_init (mpq_t DEST_RATIONAL)
+ Initialize DEST_RATIONAL and set it to 0/1. Each variable should
+ normally only be initialized once, or at least cleared out (using
+ the function `mpq_clear') between each initialization.
+
+ - Function: void mpq_clear (mpq_t RATIONAL_NUMBER)
+ Free the space occupied by RATIONAL_NUMBER. Make sure to call this
+ function for all `mpq_t' variables when you are done with them.
+
+ - Function: void mpq_set (mpq_t ROP, mpq_t OP)
+ - Function: void mpq_set_z (mpq_t ROP, mpz_t OP)
+ Assign ROP from OP.
+
+ - Function: void mpq_set_ui (mpq_t ROP, unsigned long int OP1,
+ unsigned long int OP2)
+ - Function: void mpq_set_si (mpq_t ROP, signed long int OP1, unsigned
+ long int OP2)
+ Set the value of ROP to OP1/OP2. Note that if OP1 and OP2 have
+ common factors, ROP has to be passed to `mpq_canonicalize' before
+ any operations are performed on ROP.
+
+
+File: gmp.info, Node: Assigning Rationals, Next: Comparing Rationals, Prev: Initializing Rationals, Up: Rational Number Functions
+
+Arithmetic Functions
+====================
+
+ - Function: void mpq_add (mpq_t SUM, mpq_t ADDEND1, mpq_t ADDEND2)
+ Set SUM to ADDEND1 + ADDEND2.
+
+ - Function: void mpq_sub (mpq_t DIFFERENCE, mpq_t MINUEND, mpq_t
+ SUBTRAHEND)
+ Set DIFFERENCE to MINUEND - SUBTRAHEND.
+
+ - Function: void mpq_mul (mpq_t PRODUCT, mpq_t MULTIPLIER, mpq_t
+ MULTIPLICAND)
+ Set PRODUCT to MULTIPLIER times MULTIPLICAND.
+
+ - Function: void mpq_div (mpq_t QUOTIENT, mpq_t DIVIDEND, mpq_t
+ DIVISOR)
+ Set QUOTIENT to DIVIDEND/DIVISOR.
+
+ - Function: void mpq_neg (mpq_t NEGATED_OPERAND, mpq_t OPERAND)
+ Set NEGATED_OPERAND to -OPERAND.
+
+ - Function: void mpq_inv (mpq_t INVERTED_NUMBER, mpq_t NUMBER)
+ Set INVERTED_NUMBER to 1/NUMBER. If the new denominator is zero,
+ this routine will divide by zero.
+
+
+File: gmp.info, Node: Comparing Rationals, Next: Applying Integer Functions, Prev: Assigning Rationals, Up: Rational Number Functions
+
+Comparison Functions
+====================
+
+ - Function: int mpq_cmp (mpq_t OP1, mpq_t OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ To determine if two rationals are equal, `mpq_equal' is faster than
+ `mpq_cmp'.
+
+ - Macro: int mpq_cmp_ui (mpq_t OP1, unsigned long int NUM2, unsigned
+ long int DEN2)
+ Compare OP1 and NUM2/DEN2. Return a positive value if OP1 >
+ NUM2/DEN2, zero if OP1 = NUM2/DEN2, and a negative value if OP1 <
+ NUM2/DEN2.
+
+ This routine allows that NUM2 and DEN2 have common factors.
+
+ This function is actually implemented as a macro. It evaluates its
+ arguments multiple times.
+
+ - Macro: int mpq_sgn (mpq_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates its
+ arguments multiple times.
+
+ - Function: int mpq_equal (mpq_t OP1, mpq_t OP2)
+ Return non-zero if OP1 and OP2 are equal, zero if they are
+ non-equal. Although `mpq_cmp' can be used for the same purpose,
+ this function is much faster.
+
+
+File: gmp.info, Node: Applying Integer Functions, Next: Miscellaneous Rational Functions, Prev: Comparing Rationals, Up: Rational Number Functions
+
+Applying Integer Functions to Rationals
+=======================================
+
+ The set of `mpq' functions is quite small. In particular, there are
+no functions for either input or output. But there are two macros that
+allow us to apply any `mpz' function on the numerator or denominator of
+a rational number. If these macros are used to assign to the rational
+number, `mpq_canonicalize' normally need to be called afterwards.
+
+ - Macro: mpz_t mpq_numref (mpq_t OP)
+ - Macro: mpz_t mpq_denref (mpq_t OP)
+ Return a reference to the numerator and denominator of OP,
+ respectively. The `mpz' functions can be used on the result of
+ these macros.
+
+
+File: gmp.info, Node: Miscellaneous Rational Functions, Prev: Applying Integer Functions, Up: Rational Number Functions
+
+Miscellaneous Functions
+=======================
+
+ - Function: double mpq_get_d (mpq_t OP)
+ Convert OP to a double.
+
+ These functions assign between either the numerator or denominator
+of a rational, and an integer. Instead of using these functions, it is
+preferable to use the more general mechanisms `mpq_numref' and
+`mpq_denref', together with `mpz_set'.
+
+ - Function: void mpq_set_num (mpq_t RATIONAL, mpz_t NUMERATOR)
+ Copy NUMERATOR to the numerator of RATIONAL. When this risks to
+ make the numerator and denominator of RATIONAL have common
+ factors, you have to pass RATIONAL to `mpq_canonicalize' before
+ any operations are performed on RATIONAL.
+
+ This function is equivalent to `mpz_set (mpq_numref (RATIONAL),
+ NUMERATOR)'.
+
+ - Function: void mpq_set_den (mpq_t RATIONAL, mpz_t DENOMINATOR)
+ Copy DENOMINATOR to the denominator of RATIONAL. When this risks
+ to make the numerator and denominator of RATIONAL have common
+ factors, or if the denominator might be negative, you have to pass
+ RATIONAL to `mpq_canonicalize' before any operations are performed
+ on RATIONAL.
+
+ *In version 1 of the library, negative denominators were handled by
+ copying the sign to the numerator. That is no longer done.*
+
+ This function is equivalent to `mpz_set (mpq_denref (RATIONAL),
+ DENOMINATORS)'.
+
+ - Function: void mpq_get_num (mpz_t NUMERATOR, mpq_t RATIONAL)
+ Copy the numerator of RATIONAL to the integer NUMERATOR, to
+ prepare for integer operations on the numerator.
+
+ This function is equivalent to `mpz_set (NUMERATOR, mpq_numref
+ (RATIONAL))'.
+
+ - Function: void mpq_get_den (mpz_t DENOMINATOR, mpq_t RATIONAL)
+ Copy the denominator of RATIONAL to the integer DENOMINATOR, to
+ prepare for integer operations on the denominator.
+
+ This function is equivalent to `mpz_set (DENOMINATOR, mpq_denref
+ (RATIONAL))'.
+
diff --git a/gnu/lib/libgmp/gmp.info-2 b/gnu/lib/libgmp/gmp.info-2
new file mode 100644
index 0000000..7a92755
--- /dev/null
+++ b/gnu/lib/libgmp/gmp.info-2
@@ -0,0 +1,1035 @@
+This is Info file gmp.info, produced by Makeinfo-1.64 from the input
+file gmp.texi.
+
+START-INFO-DIR-ENTRY
+* gmp: (gmp.info). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+ This file documents GNU MP, a library for arbitrary-precision
+arithmetic.
+
+ Copyright (C) 1991, 1993, 1994, 1995, 1996 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 Foundation.
+
+
+File: gmp.info, Node: Floating-point Functions, Next: Low-level Functions, Prev: Rational Number Functions, Up: Top
+
+Floating-point Functions
+************************
+
+ This is a description of the *preliminary* interface for
+floating-point arithmetic in GNU MP 2.
+
+ The floating-point functions expect arguments of type `mpf_t'.
+
+ The MP floating-point functions have an interface that is similar to
+the MP integer functions. The function prefix for floating-point
+operations is `mpf_'.
+
+ There is one significant characteristic of floating-point numbers
+that has motivated a difference between this function class and other
+MP function classes: the inherent inexactness of floating point
+arithmetic. The user has to specify the precision of each variable. A
+computation that assigns a variable will take place with the precision
+of the assigned variable; the precision of variables used as input is
+ignored.
+
+ The precision of a calculation is defined as follows: Compute the
+requested operation exactly (with "infinite precision"), and truncate
+the result to the destination variable precision. Even if the user has
+asked for a very high precision, MP will not calculate with superfluous
+digits. For example, if two low-precision numbers of nearly equal
+magnitude are added, the precision of the result will be limited to
+what is required to represent the result accurately.
+
+ The MP floating-point functions are *not* intended as a smooth
+extension to the IEEE P754 arithmetic. Specifically, the results
+obtained on one computer often differs from the results obtained on a
+computer with a different word size.
+
+* Menu:
+
+* Initializing Floats::
+* Assigning Floats::
+* Simultaneous Float Init & Assign::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+
+
+File: gmp.info, Node: Initializing Floats, Next: Assigning Floats, Up: Floating-point Functions
+
+Initialization and Assignment Functions
+=======================================
+
+ - Function: void mpf_set_default_prec (unsigned long int PREC)
+ Set the default precision to be *at least* PREC bits. All
+ subsequent calls to `mpf_init' will use this precision, but
+ previously initialized variables are unaffected.
+
+ An `mpf_t' object must be initialized before storing the first value
+in it. The functions `mpf_init' and `mpf_init2' are used for that
+purpose.
+
+ - Function: void mpf_init (mpf_t X)
+ Initialize X to 0. Normally, a variable should be initialized
+ once only or at least be cleared, using `mpf_clear', between
+ initializations. The precision of X is undefined unless a default
+ precision has already been established by a call to
+ `mpf_set_default_prec'.
+
+ - Function: void mpf_init2 (mpf_t X, unsigned long int PREC)
+ Initialize X to 0 and set its precision to be *at least* PREC
+ bits. Normally, a variable should be initialized once only or at
+ least be cleared, using `mpf_clear', between initializations.
+
+ - Function: void mpf_clear (mpf_t X)
+ Free the space occupied by X. Make sure to call this function for
+ all `mpf_t' variables when you are done with them.
+
+ Here is an example on how to initialize floating-point variables:
+ {
+ mpf_t x, y;
+ mpf_init (x); /* use default precision */
+ mpf_init2 (y, 256); /* precision *at least* 256 bits */
+ ...
+ /* Unless the program is about to exit, do ... */
+ mpf_clear (x);
+ mpf_clear (y);
+ }
+
+ The following three functions are useful for changing the precision
+during a calculation. A typical use would be for adjusting the
+precision gradually in iterative algorithms like Newton-Raphson, making
+the computation precision closely match the actual accurate part of the
+numbers.
+
+ - Function: void mpf_set_prec (mpf_t ROP, unsigned long int PREC)
+ Set the precision of ROP to be *at least* PREC bits. Since
+ changing the precision involves calls to `realloc', this routine
+ should not be called in a tight loop.
+
+ - Function: unsigned long int mpf_get_prec (mpf_t OP)
+ Return the precision actually used for assignments of OP.
+
+ - Function: void mpf_set_prec_raw (mpf_t ROP, unsigned long int PREC)
+ Set the precision of ROP to be *at least* PREC bits. This is a
+ low-level function that does not change the allocation. The PREC
+ argument must not be larger that the precision previously returned
+ by `mpf_get_prec'. It is crucial that the precision of ROP is
+ ultimately reset to exactly the value returned by `mpf_get_prec'.
+
+
+File: gmp.info, Node: Assigning Floats, Next: Simultaneous Float Init & Assign, Prev: Initializing Floats, Up: Floating-point Functions
+
+Assignment Functions
+--------------------
+
+ These functions assign new values to already initialized floats
+(*note Initializing Floats::.).
+
+ - Function: void mpf_set (mpf_t ROP, mpf_t OP)
+ - Function: void mpf_set_ui (mpf_t ROP, unsigned long int OP)
+ - Function: void mpf_set_si (mpf_t ROP, signed long int OP)
+ - Function: void mpf_set_d (mpf_t ROP, double OP)
+ - Function: void mpf_set_z (mpf_t ROP, mpz_t OP)
+ - Function: void mpf_set_q (mpf_t ROP, mpq_t OP)
+ Set the value of ROP from OP.
+
+ - Function: int mpf_set_str (mpf_t ROP, char *STR, int BASE)
+ Set the value of ROP from the string in STR. The string is of the
+ form `M@N' or, if the base is 10 or less, alternatively `MeN'.
+ `M' is the mantissa and `N' is the exponent. The mantissa is
+ always in the specified base. The exponent is either in the
+ specified base or, if BASE is negative, in decimal.
+
+ The argument BASE may be in the ranges 2 to 36, or -36 to -2.
+ Negative values are used to specify that the exponent is in
+ decimal.
+
+ Unlike the corresponding `mpz' function, the base will not be
+ determined from the leading characters of the string if BASE is 0.
+ This is so that numbers like `0.23' are not interpreted as octal.
+
+ White space is allowed in the string, and is simply ignored.
+
+ This function returns 0 if the entire string up to the '\0' is a
+ valid number in base BASE. Otherwise it returns -1.
+
+
+File: gmp.info, Node: Simultaneous Float Init & Assign, Next: Converting Floats, Prev: Assigning Floats, Up: Floating-point Functions
+
+Combined Initialization and Assignment Functions
+------------------------------------------------
+
+ For convenience, MP provides a parallel series of initialize-and-set
+functions which initialize the output and then store the value there.
+These functions' names have the form `mpf_init_set...'
+
+ Once the float has been initialized by any of the `mpf_init_set...'
+functions, it can be used as the source or destination operand for the
+ordinary float functions. Don't use an initialize-and-set function on
+a variable already initialized!
+
+ - Function: void mpf_init_set (mpf_t ROP, mpf_t OP)
+ - Function: void mpf_init_set_ui (mpf_t ROP, unsigned long int OP)
+ - Function: void mpf_init_set_si (mpf_t ROP, signed long int OP)
+ - Function: void mpf_init_set_d (mpf_t ROP, double OP)
+ Initialize ROP and set its value from OP.
+
+ The precision of ROP will be taken from the active default
+ precision, as set by `mpf_set_default_prec'.
+
+ - Function: int mpf_init_set_str (mpf_t ROP, char *STR, int BASE)
+ Initialize ROP and set its value from the string in STR. See
+ `mpf_set_str' above for details on the assignment operation.
+
+ Note that ROP is initialized even if an error occurs. (I.e., you
+ have to call `mpf_clear' for it.)
+
+ The precision of ROP will be taken from the active default
+ precision, as set by `mpf_set_default_prec'.
+
+
+File: gmp.info, Node: Converting Floats, Next: Float Arithmetic, Prev: Simultaneous Float Init & Assign, Up: Floating-point Functions
+
+Conversion Functions
+====================
+
+ - Function: double mpf_get_d (mpf_t OP)
+ Convert OP to a double.
+
+ - Function: char * mpf_get_str (char *STR, mp_exp_t *EXPPTR, int BASE,
+ size_t N_DIGITS, mpf_t OP)
+ Convert OP to a string of digits in base BASE. The base may vary
+ from 2 to 36. Generate at most N_DIGITS significant digits, or if
+ N_DIGITS is 0, the maximum number of digits accurately
+ representable by OP.
+
+ If STR is NULL, space for the mantissa is allocated using the
+ default allocation function, and a pointer to the string is
+ returned.
+
+ If STR is not NULL, it should point to a block of storage enough
+ large for the mantissa, i.e., N_DIGITS + 2. The two extra bytes
+ are for a possible minus sign, and for the terminating null
+ character.
+
+ The exponent is written through the pointer EXPPTR.
+
+ If N_DIGITS is 0, the maximum number of digits meaningfully
+ achievable from the precision of OP will be generated. Note that
+ the space requirements for STR in this case will be impossible for
+ the user to predetermine. Therefore, you need to pass NULL for
+ the string argument whenever N_DIGITS is 0.
+
+ The generated string is a fraction, with an implicit radix point
+ immediately to the left of the first digit. For example, the
+ number 3.1416 would be returned as "31416" in the string and 1
+ written at EXPPTR.
+
+
+File: gmp.info, Node: Float Arithmetic, Next: Float Comparison, Prev: Converting Floats, Up: Floating-point Functions
+
+Arithmetic Functions
+====================
+
+ - Function: void mpf_add (mpf_t ROP, mpf_t OP1, mpf_t OP2)
+ - Function: void mpf_add_ui (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 + OP2.
+
+ - Function: void mpf_sub (mpf_t ROP, mpf_t OP1, mpf_t OP2)
+ - Function: void mpf_ui_sub (mpf_t ROP, unsigned long int OP1, mpf_t
+ OP2)
+ - Function: void mpf_sub_ui (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 - OP2.
+
+ - Function: void mpf_mul (mpf_t ROP, mpf_t OP1, mpf_t OP2)
+ - Function: void mpf_mul_ui (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 times OP2.
+
+ Division is undefined if the divisor is zero, and passing a zero
+divisor to the divide functions will make these functions intentionally
+divide by zero. This gives the user the possibility to handle
+arithmetic exceptions in these functions in the same manner as other
+arithmetic exceptions.
+
+ - Function: void mpf_div (mpf_t ROP, mpf_t OP1, mpf_t OP2)
+ - Function: void mpf_ui_div (mpf_t ROP, unsigned long int OP1, mpf_t
+ OP2)
+ - Function: void mpf_div_ui (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1/OP2.
+
+ - Function: void mpf_sqrt (mpf_t ROP, mpf_t OP)
+ - Function: void mpf_sqrt_ui (mpf_t ROP, unsigned long int OP)
+ Set ROP to the square root of OP.
+
+ - Function: void mpf_neg (mpf_t ROP, mpf_t OP)
+ Set ROP to -OP.
+
+ - Function: void mpf_abs (mpf_t ROP, mpf_t OP)
+ Set ROP to the absolute value of OP.
+
+ - Function: void mpf_mul_2exp (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 times 2 raised to OP2.
+
+ - Function: void mpf_div_2exp (mpf_t ROP, mpf_t OP1, unsigned long int
+ OP2)
+ Set ROP to OP1 divided by 2 raised to OP2.
+
+
+File: gmp.info, Node: Float Comparison, Next: I/O of Floats, Prev: Float Arithmetic, Up: Floating-point Functions
+
+Comparison Functions
+====================
+
+ - Function: int mpf_cmp (mpf_t OP1, mpf_t OP2)
+ - Function: int mpf_cmp_ui (mpf_t OP1, unsigned long int OP2)
+ - Function: int mpf_cmp_si (mpf_t OP1, signed long int OP2)
+ Compare OP1 and OP2. Return a positive value if OP1 > OP2, zero
+ if OP1 = OP2, and a negative value if OP1 < OP2.
+
+ - Function: int mpf_eq (mpf_t OP1, mpf_t OP2, unsigned long int op3)
+ Return non-zero if the first OP3 bits of OP1 and OP2 are equal,
+ zero otherwise. I.e., test of OP1 and OP2 are approximately equal.
+
+ - Function: void mpf_reldiff (mpf_t ROP, mpf_t OP1, mpf_t OP2)
+ Compute the relative difference between OP1 and OP2 and store the
+ result in ROP.
+
+ - Macro: int mpf_sgn (mpf_t OP)
+ Return +1 if OP > 0, 0 if OP = 0, and -1 if OP < 0.
+
+ This function is actually implemented as a macro. It evaluates its
+ arguments multiple times.
+
+
+File: gmp.info, Node: I/O of Floats, Next: Miscellaneous Float Functions, Prev: Float Comparison, Up: Floating-point Functions
+
+Input and Output Functions
+==========================
+
+ Functions that perform input from a stdio stream, and functions that
+output to a stdio stream. Passing a NULL pointer for a STREAM argument
+to any of these functions will make them read from `stdin' and write to
+`stdout', respectively.
+
+ When using any of these functions, it is a good idea to include
+`stdio.h' before `gmp.h', since that will allow `gmp.h' to define
+prototypes for these functions.
+
+ - Function: size_t mpf_out_str (FILE *STREAM, int BASE, size_t
+ N_DIGITS, mpf_t OP)
+ Output OP on stdio stream STREAM, as a string of digits in base
+ BASE. The base may vary from 2 to 36. Print at most N_DIGITS
+ significant digits, or if N_DIGITS is 0, the maximum number of
+ digits accurately representable by OP.
+
+ In addition to the significant digits, a leading `0.' and a
+ trailing exponent, in the form `eNNN', are printed. If BASE is
+ greater than 10, `@' will be used instead of `e' as exponent
+ delimiter.
+
+ Return the number of bytes written, or if an error occurred,
+ return 0.
+
+ - Function: size_t mpf_inp_str (mpf_t ROP, FILE *STREAM, int BASE)
+ Input a string in base BASE from stdio stream STREAM, and put the
+ read float in ROP. The string is of the form `M@N' or, if the
+ base is 10 or less, alternatively `MeN'. `M' is the mantissa and
+ `N' is the exponent. The mantissa is always in the specified
+ base. The exponent is either in the specified base or, if BASE is
+ negative, in decimal.
+
+ The argument BASE may be in the ranges 2 to 36, or -36 to -2.
+ Negative values are used to specify that the exponent is in
+ decimal.
+
+ Unlike the corresponding `mpz' function, the base will not be
+ determined from the leading characters of the string if BASE is 0.
+ This is so that numbers like `0.23' are not interpreted as octal.
+
+ Return the number of bytes read, or if an error occurred, return 0.
+
+
+File: gmp.info, Node: Miscellaneous Float Functions, Prev: I/O of Floats, Up: Floating-point Functions
+
+Miscellaneous Functions
+=======================
+
+ - Function: void mpf_random2 (mpf_t ROP, mp_size_t MAX_SIZE, mp_exp_t
+ MAX_EXP)
+ Generate a random float of at most MAX_SIZE limbs, with long
+ strings of zeros and ones in the binary representation. The
+ exponent of the number is in the interval -EXP to EXP. This
+ function is useful for testing functions and algorithms, since
+ this kind of random numbers have proven to be more likely to
+ trigger corner-case bugs. Negative random numbers are generated
+ when MAX_SIZE is negative.
+
+
+File: gmp.info, Node: Low-level Functions, Next: BSD Compatible Functions, Prev: Floating-point Functions, Up: Top
+
+Low-level Functions
+*******************
+
+ This chapter describes low-level MP functions, used to implement the
+high-level MP functions, but also intended for time-critical user code.
+
+ These functions start with the prefix `mpn_'.
+
+ The `mpn' functions are designed to be as fast as possible, *not* to
+provide a coherent calling interface. The different functions have
+somewhat similar interfaces, but there are variations that make them
+hard to use. These functions do as little as possible apart from the
+real multiple precision computation, so that no time is spent on things
+that not all callers need.
+
+ A source operand is specified by a pointer to the least significant
+limb and a limb count. A destination operand is specified by just a
+pointer. It is the responsibility of the caller to ensure that the
+destination has enough space for storing the result.
+
+ With this way of specifying operands, it is possible to perform
+computations on subranges of an argument, and store the result into a
+subrange of a destination.
+
+ A common requirement for all functions is that each source area
+needs at least one limb. No size argument may be zero.
+
+ The `mpn' functions is the base for the implementation of the `mpz_',
+`mpf_', and `mpq_' functions.
+
+ This example adds the number beginning at SRC1_PTR and the number
+beginning at SRC2_PTR and writes the sum at DEST_PTR. All areas have
+SIZE limbs.
+
+ cy = mpn_add_n (dest_ptr, src1_ptr, src2_ptr, size)
+
+In the notation used here, a source operand is identified by the
+pointer to the least significant limb, and the limb count in braces.
+For example, {s1_ptr, s1_size}.
+
+ - Function: mp_limb_t mpn_add_n (mp_limb_t * DEST_PTR, const mp_limb_t
+ * SRC1_PTR, const mp_limb_t * SRC2_PTR, mp_size_t SIZE)
+ Add {SRC1_PTR, SIZE} and {SRC2_PTR, SIZE}, and write the SIZE
+ least significant limbs of the result to DEST_PTR. Return carry,
+ either 0 or 1.
+
+ This is the lowest-level function for addition. It is the
+ preferred function for addition, since it is written in assembly
+ for most targets. For addition of a variable to itself (i.e.,
+ SRC1_PTR equals SRC2_PTR, use `mpn_lshift' with a count of 1 for
+ optimal speed.
+
+ - Function: mp_limb_t mpn_add_1 (mp_limb_t * DEST_PTR, const mp_limb_t
+ * SRC1_PTR, mp_size_t SIZE, mp_limb_t SRC2_LIMB)
+ Add {SRC1_PTR, SIZE} and SRC2_LIMB, and write the SIZE least
+ significant limbs of the result to DEST_PTR. Return carry, either
+ 0 or 1.
+
+ - Function: mp_limb_t mpn_add (mp_limb_t * DEST_PTR, const mp_limb_t *
+ SRC1_PTR, mp_size_t SRC1_SIZE, const mp_limb_t * SRC2_PTR,
+ mp_size_t SRC2_SIZE)
+ Add {SRC1_PTR, SRC1_SIZE} and {SRC2_PTR, SRC2_SIZE}, and write the
+ SRC1_SIZE least significant limbs of the result to DEST_PTR.
+ Return carry, either 0 or 1.
+
+ This function requires that SRC1_SIZE is greater than or equal to
+ SRC2_SIZE.
+
+ - Function: mp_limb_t mpn_sub_n (mp_limb_t * DEST_PTR, const mp_limb_t
+ * SRC1_PTR, const mp_limb_t * SRC2_PTR, mp_size_t SIZE)
+ Subtract {SRC2_PTR, SRC2_SIZE} from {SRC1_PTR, SIZE}, and write
+ the SIZE least significant limbs of the result to DEST_PTR.
+ Return borrow, either 0 or 1.
+
+ This is the lowest-level function for subtraction. It is the
+ preferred function for subtraction, since it is written in
+ assembly for most targets.
+
+ - Function: mp_limb_t mpn_sub_1 (mp_limb_t * DEST_PTR, const mp_limb_t
+ * SRC1_PTR, mp_size_t SIZE, mp_limb_t SRC2_LIMB)
+ Subtract SRC2_LIMB from {SRC1_PTR, SIZE}, and write the SIZE least
+ significant limbs of the result to DEST_PTR. Return borrow,
+ either 0 or 1.
+
+ - Function: mp_limb_t mpn_sub (mp_limb_t * DEST_PTR, const mp_limb_t *
+ SRC1_PTR, mp_size_t SRC1_SIZE, const mp_limb_t * SRC2_PTR,
+ mp_size_t SRC2_SIZE)
+ Subtract {SRC2_PTR, SRC2_SIZE} from {SRC1_PTR, SRC1_SIZE}, and
+ write the SRC1_SIZE least significant limbs of the result to
+ DEST_PTR. Return borrow, either 0 or 1.
+
+ This function requires that SRC1_SIZE is greater than or equal to
+ SRC2_SIZE.
+
+ - Function: void mpn_mul_n (mp_limb_t * DEST_PTR, const mp_limb_t *
+ SRC1_PTR, const mp_limb_t * SRC2_PTR, mp_size_t SIZE)
+ Multiply {SRC1_PTR, SIZE} and {SRC2_PTR, SIZE}, and write the
+ *entire* result to DEST_PTR.
+
+ The destination has to have space for 2SIZE limbs, even if the
+ significant result might be one limb smaller.
+
+ - Function: mp_limb_t mpn_mul_1 (mp_limb_t * DEST_PTR, const mp_limb_t
+ * SRC1_PTR, mp_size_t SIZE, mp_limb_t SRC2_LIMB)
+ Multiply {SRC1_PTR, SIZE} and SRC2_LIMB, and write the SIZE least
+ significant limbs of the product to DEST_PTR. Return the most
+ significant limb of the product.
+
+ This is a low-level function that is a building block for general
+ multiplication as well as other operations in MP. It is written
+ in assembly for most targets.
+
+ Don't call this function if SRC2_LIMB is a power of 2; use
+ `mpn_lshift' with a count equal to the logarithm of SRC2_LIMB
+ instead, for optimal speed.
+
+ - Function: mp_limb_t mpn_addmul_1 (mp_limb_t * DEST_PTR, const
+ mp_limb_t * SRC1_PTR, mp_size_t SIZE, mp_limb_t SRC2_LIMB)
+ Multiply {SRC1_PTR, SIZE} and SRC2_LIMB, and add the SIZE least
+ significant limbs of the product to {DEST_PTR, SIZE} and write the
+ result to DEST_PTR DEST_PTR. Return the most significant limb of
+ the product, plus carry-out from the addition.
+
+ This is a low-level function that is a building block for general
+ multiplication as well as other operations in MP. It is written
+ in assembly for most targets.
+
+ - Function: mp_limb_t mpn_submul_1 (mp_limb_t * DEST_PTR, const
+ mp_limb_t * SRC1_PTR, mp_size_t SIZE, mp_limb_t SRC2_LIMB)
+ Multiply {SRC1_PTR, SIZE} and SRC2_LIMB, and subtract the SIZE
+ least significant limbs of the product from {DEST_PTR, SIZE} and
+ write the result to DEST_PTR. Return the most significant limb of
+ the product, minus borrow-out from the subtraction.
+
+ This is a low-level function that is a building block for general
+ multiplication and division as well as other operations in MP. It
+ is written in assembly for most targets.
+
+ - Function: mp_limb_t mpn_mul (mp_limb_t * DEST_PTR, const mp_limb_t *
+ SRC1_PTR, mp_size_t SRC1_SIZE, const mp_limb_t * SRC2_PTR,
+ mp_size_t SRC2_SIZE)
+ Multiply {SRC1_PTR, SRC1_SIZE} and {SRC2_PTR, SRC2_SIZE}, and
+ write the result to DEST_PTR. Return the most significant limb of
+ the result.
+
+ The destination has to have space for SRC1_SIZE + SRC1_SIZE limbs,
+ even if the result might be one limb smaller.
+
+ This function requires that SRC1_SIZE is greater than or equal to
+ SRC2_SIZE. The destination must be distinct from either input
+ operands.
+
+ - Function: mp_size_t mpn_divrem (mp_limb_t * R1P, mp_size_t XSIZE,
+ mp_limb_t * RS2P, mp_size_t RS2SIZE, const mp_limb_t * S3P,
+ mp_size_t S3SIZE)
+ Divide {RS2P, RS2SIZE} by {S3P, S3SIZE}, and write the quotient at
+ R1P, with the exception of the most significant limb, which is
+ returned. The remainder replaces the dividend at RS2P.
+
+ In addition to an integer quotient, XSIZE fraction limbs are
+ developed, and stored after the integral limbs. For most usages,
+ XSIZE will be zero.
+
+ It is required that RS2SIZE is greater than or equal to S3SIZE.
+ It is required that the most significant bit of the divisor is set.
+
+ If the quotient is not needed, pass RS2P + S3SIZE as R1P. Aside
+ from that special case, no overlap between arguments is permitted.
+
+ Return the most significant limb of the quotient, either 0 or 1.
+
+ The area at R1P needs to be RS2SIZE - S3SIZE + XSIZE limbs large.
+
+ - Function: mp_limb_t mpn_divrem_1 (mp_limb_t * R1P, mp_size_t XSIZE,
+ mp_limb_t * S2P, mp_size_t S2SIZE, mp_limb_t S3LIMB)
+ Divide {S2P, S2SIZE} by S3LIMB, and write the quotient at R1P.
+ Return the remainder.
+
+ In addition to an integer quotient, XSIZE fraction limbs are
+ developed, and stored after the integral limbs. For most usages,
+ XSIZE will be zero.
+
+ The areas at R1P and S2P have to be identical or completely
+ separate, not partially overlapping.
+
+ - Function: mp_size_t mpn_divmod (mp_limb_t * R1P, mp_limb_t * RS2P,
+ mp_size_t RS2SIZE, const mp_limb_t * S3P, mp_size_t S3SIZE)
+ *This interface is obsolete. It will disappear from future
+ releases. Use `mpn_divrem' in its stead.*
+
+ - Function: mp_limb_t mpn_divmod_1 (mp_limb_t * R1P, mp_limb_t * S2P,
+ mp_size_t S2SIZE, mp_limb_t S3LIMB)
+ *This interface is obsolete. It will disappear from future
+ releases. Use `mpn_divrem_1' in its stead.*
+
+ - Function: mp_limb_t mpn_mod_1 (mp_limb_t * S1P, mp_size_t S1SIZE,
+ mp_limb_t S2LIMB)
+ Divide {S1P, S1SIZE} by S2LIMB, and return the remainder.
+
+ - Function: mp_limb_t mpn_preinv_mod_1 (mp_limb_t * S1P, mp_size_t
+ S1SIZE, mp_limb_t S2LIMB, mp_limb_t S3LIMB)
+ *This interface is obsolete. It will disappear from future
+ releases. Use `mpn_mod_1' in its stead.*
+
+ - Function: mp_limb_t mpn_bdivmod (mp_limb_t * DEST_PTR, mp_limb_t *
+ S1P, mp_size_t S1SIZE, const mp_limb_t * S2P, mp_size_t
+ S2SIZE, unsigned long int D)
+ The function puts the low [D/BITS_PER_MP_LIMB] limbs of Q = {S1P,
+ S1SIZE}/{S2P, S2SIZE} mod 2^D at DEST_PTR, and returns the high D
+ mod BITS_PER_MP_LIMB bits of Q.
+
+ {S1P, S1SIZE} - Q * {S2P, S2SIZE} mod 2^(S1SIZE*BITS_PER_MP_LIMB)
+ is placed at S1P. Since the low [D/BITS_PER_MP_LIMB] limbs of
+ this difference are zero, it is possible to overwrite the low
+ limbs at S1P with this difference, provided DEST_PTR <= S1P.
+
+ This function requires that S1SIZE * BITS_PER_MP_LIMB >= D, and
+ that {S2P, S2SIZE} is odd.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: mp_limb_t mpn_lshift (mp_limb_t * DEST_PTR, const
+ mp_limb_t * SRC_PTR, mp_size_t SRC_SIZE, unsigned long int
+ COUNT)
+ Shift {SRC_PTR, SRC_SIZE} COUNT bits to the left, and write the
+ SRC_SIZE least significant limbs of the result to DEST_PTR. COUNT
+ might be in the range 1 to n - 1, on an n-bit machine. The bits
+ shifted out to the left are returned.
+
+ Overlapping of the destination space and the source space is
+ allowed in this function, provided DEST_PTR >= SRC_PTR.
+
+ This function is written in assembly for most targets.
+
+ - Function: mp_limp_t mpn_rshift (mp_limb_t * DEST_PTR, const
+ mp_limb_t * SRC_PTR, mp_size_t SRC_SIZE, unsigned long int
+ COUNT)
+ Shift {SRC_PTR, SRC_SIZE} COUNT bits to the right, and write the
+ SRC_SIZE most significant limbs of the result to DEST_PTR. COUNT
+ might be in the range 1 to n - 1, on an n-bit machine. The bits
+ shifted out to the right are returned.
+
+ Overlapping of the destination space and the source space is
+ allowed in this function, provided DEST_PTR <= SRC_PTR.
+
+ This function is written in assembly for most targets.
+
+ - Function: int mpn_cmp (const mp_limb_t * SRC1_PTR, const mp_limb_t *
+ SRC2_PTR, mp_size_t SIZE)
+ Compare {SRC1_PTR, SIZE} and {SRC2_PTR, SIZE} and return a
+ positive value if src1 > src2, 0 of they are equal, and a negative
+ value if src1 < src2.
+
+ - Function: mp_size_t mpn_gcd (mp_limb_t * DEST_PTR, mp_limb_t *
+ SRC1_PTR, mp_size_t SRC1_SIZE, mp_limb_t * SRC2_PTR,
+ mp_size_t SRC2_SIZE)
+ Puts at DEST_PTR the greatest common divisor of {SRC1_PTR,
+ SRC1_SIZE} and {SRC2_PTR, SRC2_SIZE}; both source operands are
+ destroyed by the operation. The size in limbs of the greatest
+ common divisor is returned.
+
+ {SRC1_PTR, SRC1_SIZE} must be odd, and {SRC2_PTR, SRC2_SIZE} must
+ have at least as many bits as {SRC1_PTR, SRC1_SIZE}.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: mp_limb_t mpn_gcd_1 (const mp_limb_t * SRC1_PTR, mp_size_t
+ SRC1_SIZE, mp_limb_t SRC2_LIMB)
+ Return the greatest common divisor of {SRC1_PTR, SRC1_SIZE} and
+ SRC2_LIMB, where SRC2_LIMB (as well as SRC1_SIZE) must be
+ different from 0.
+
+ - Function: mp_size_t mpn_gcdext (mp_limb_t * R1P, mp_limb_t * R2P,
+ mp_limb_t * S1P, mp_size_t S1SIZE, mp_limb_t * S2P, mp_size_t
+ S2SIZE)
+ Puts at R1P the greatest common divisor of {S1P, S1SIZE} and {S2P,
+ S2SIZE}. The first cofactor is written at R2P. Both source
+ operands are destroyed by the operation. The size in limbs of the
+ greatest common divisor is returned.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: mp_size_t mpn_sqrtrem (mp_limb_t * R1P, mp_limb_t * R2P,
+ const mp_limb_t * SP, mp_size_t SIZE)
+ Compute the square root of {SP, SIZE} and put the result at R1P.
+ Write the remainder at R2P, unless R2P is NULL.
+
+ Return the size of the remainder, whether R2P was NULL or non-NULL.
+ Iff the operand was a perfect square, the return value will be 0.
+
+ The areas at R1P and SP have to be distinct. The areas at R2P and
+ SP have to be identical or completely separate, not partially
+ overlapping.
+
+ The area at R1P needs to have space for ceil(SIZE/2) limbs. The
+ area at R2P needs to be SIZE limbs large.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: mp_size_t mpn_get_str (unsigned char *STR, int BASE,
+ mp_limb_t * S1P, mp_size_t S1SIZE)
+ Convert {S1P, S1SIZE} to a raw unsigned char array in base BASE.
+ The string is not in ASCII; to convert it to printable format, add
+ the ASCII codes for `0' or `A', depending on the base and range.
+ There may be leading zeros in the string.
+
+ The area at S1P is clobbered.
+
+ Return the number of characters in STR.
+
+ The area at STR has to have space for the largest possible number
+ represented by a S1SIZE long limb array, plus one extra character.
+
+ - Function: mp_size_t mpn_set_str (mp_limb_t * R1P, const char *STR,
+ size_t strsize, int BASE)
+ Convert the raw unsigned char array at STR of length STRSIZE to a
+ limb array {S1P, S1SIZE}. The base of STR is BASE.
+
+ Return the number of limbs stored in R1P.
+
+ - Function: unsigned long int mpn_scan0 (const mp_limb_t * S1P,
+ unsigned long int BIT)
+ Scan S1P from bit position BIT for the next clear bit.
+
+ It is required that there be a clear bit within the area at S1P at
+ or beyond bit position BIT, so that the function has something to
+ return.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: unsigned long int mpn_scan1 (const mp_limb_t * S1P,
+ unsigned long int BIT)
+ Scan S1P from bit position BIT for the next set bit.
+
+ It is required that there be a set bit within the area at S1P at or
+ beyond bit position BIT, so that the function has something to
+ return.
+
+ *This interface is preliminary. It might change incompatibly in
+ future revisions.*
+
+ - Function: void mpn_random2 (mp_limb_t * R1P, mp_size_t R1SIZE)
+ Generate a random number of length R1SIZE with long strings of
+ zeros and ones in the binary representation, and store it at R1P.
+
+ The generated random numbers are intended for testing the
+ correctness of the implementation of the `mpn' routines.
+
+ - Function: unsigned long int mpn_popcount (const mp_limb_t * S1P,
+ unsigned long int SIZE)
+ Count the number of set bits in {S1P, SIZE}.
+
+ - Function: unsigned long int mpn_hamdist (const mp_limb_t * S1P,
+ const mp_limb_t * S2P, unsigned long int SIZE)
+ Compute the hamming distance between {S1P, SIZE} and {S2P, SIZE}.
+
+ - Function: int mpn_perfect_square_p (const mp_limb_t * S1P, mp_size_t
+ SIZE)
+ Return non-zero iff {S1P, SIZE} is a perfect square.
+
+
+File: gmp.info, Node: BSD Compatible Functions, Next: Custom Allocation, Prev: Low-level Functions, Up: Top
+
+Berkeley MP Compatible Functions
+********************************
+
+ These functions are intended to be fully compatible with the
+Berkeley MP library which is available on many BSD derived U*ix systems.
+
+ The original Berkeley MP library has a usage restriction: you cannot
+use the same variable as both source and destination in a single
+function call. The compatible functions in GNU MP do not share this
+restriction--inputs and outputs may overlap.
+
+ It is not recommended that new programs are written using these
+functions. Apart from the incomplete set of functions, the interface
+for initializing `MINT' objects is more error prone, and the `pow'
+function collides with `pow' in `libm.a'.
+
+ Include the header `mp.h' to get the definition of the necessary
+types and functions. If you are on a BSD derived system, make sure to
+include GNU `mp.h' if you are going to link the GNU `libmp.a' to you
+program. This means that you probably need to give the -I<dir> option
+to the compiler, where <dir> is the directory where you have GNU `mp.h'.
+
+ - Function: MINT * itom (signed short int INITIAL_VALUE)
+ Allocate an integer consisting of a `MINT' object and dynamic limb
+ space. Initialize the integer to INITIAL_VALUE. Return a pointer
+ to the `MINT' object.
+
+ - Function: MINT * xtom (char *INITIAL_VALUE)
+ Allocate an integer consisting of a `MINT' object and dynamic limb
+ space. Initialize the integer from INITIAL_VALUE, a hexadecimal,
+ '\0'-terminate C string. Return a pointer to the `MINT' object.
+
+ - Function: void move (MINT *SRC, MINT *DEST)
+ Set DEST to SRC by copying. Both variables must be previously
+ initialized.
+
+ - Function: void madd (MINT *SRC_1, MINT *SRC_2, MINT *DESTINATION)
+ Add SRC_1 and SRC_2 and put the sum in DESTINATION.
+
+ - Function: void msub (MINT *SRC_1, MINT *SRC_2, MINT *DESTINATION)
+ Subtract SRC_2 from SRC_1 and put the difference in DESTINATION.
+
+ - Function: void mult (MINT *SRC_1, MINT *SRC_2, MINT *DESTINATION)
+ Multiply SRC_1 and SRC_2 and put the product in DESTINATION.
+
+ - Function: void mdiv (MINT *DIVIDEND, MINT *DIVISOR, MINT *QUOTIENT,
+ MINT *REMAINDER)
+ - Function: void sdiv (MINT *DIVIDEND, signed short int DIVISOR, MINT
+ *QUOTIENT, signed short int *REMAINDER)
+ Set QUOTIENT to DIVIDEND/DIVISOR, and REMAINDER to DIVIDEND mod
+ DIVISOR. The quotient is rounded towards zero; the remainder has
+ the same sign as the dividend unless it is zero.
+
+ Some implementations of these functions work differently--or not
+ at all--for negative arguments.
+
+ - Function: void msqrt (MINT *OPERAND, MINT *ROOT, MINT *REMAINDER)
+ Set ROOT to the truncated integer part of the square root of
+ OPERAND. Set REMAINDER to OPERAND-ROOT*ROOT, (i.e., zero if
+ OPERAND is a perfect square).
+
+ If ROOT and REMAINDER are the same variable, the results are
+ undefined.
+
+ - Function: void pow (MINT *BASE, MINT *EXP, MINT *MOD, MINT *DEST)
+ Set DEST to (BASE raised to EXP) modulo MOD.
+
+ - Function: void rpow (MINT *BASE, signed short int EXP, MINT *DEST)
+ Set DEST to BASE raised to EXP.
+
+ - Function: void gcd (MINT *OPERAND1, MINT *OPERAND2, MINT *RES)
+ Set RES to the greatest common divisor of OPERAND1 and OPERAND2.
+
+ - Function: int mcmp (MINT *OPERAND1, MINT *OPERAND2)
+ Compare OPERAND1 and OPERAND2. Return a positive value if
+ OPERAND1 > OPERAND2, zero if OPERAND1 = OPERAND2, and a negative
+ value if OPERAND1 < OPERAND2.
+
+ - Function: void min (MINT *DEST)
+ Input a decimal string from `stdin', and put the read integer in
+ DEST. SPC and TAB are allowed in the number string, and are
+ ignored.
+
+ - Function: void mout (MINT *SRC)
+ Output SRC to `stdout', as a decimal string. Also output a
+ newline.
+
+ - Function: char * mtox (MINT *OPERAND)
+ Convert OPERAND to a hexadecimal string, and return a pointer to
+ the string. The returned string is allocated using the default
+ memory allocation function, `malloc' by default.
+
+ - Function: void mfree (MINT *OPERAND)
+ De-allocate, the space used by OPERAND. *This function should
+ only be passed a value returned by `itom' or `xtom'.*
+
+
+File: gmp.info, Node: Custom Allocation, Next: Contributors, Prev: BSD Compatible Functions, Up: Top
+
+Custom Allocation
+*****************
+
+ By default, the MP functions use `malloc', `realloc', and `free' for
+memory allocation. If `malloc' or `realloc' fails, the MP library
+terminates execution after printing a fatal error message to standard
+error.
+
+ For some applications, you may wish to allocate memory in other
+ways, or you may not want to have a fatal error when there is no more
+memory available. To accomplish this, you can specify alternative
+memory allocation functions.
+
+ - Function: void mp_set_memory_functions (
+ void *(*ALLOC_FUNC_PTR) (size_t),
+ void *(*REALLOC_FUNC_PTR) (void *, size_t, size_t),
+ void (*FREE_FUNC_PTR) (void *, size_t))
+ Replace the current allocation functions from the arguments. If
+ an argument is NULL, the corresponding default function is
+ retained.
+
+ *Make sure to call this function in such a way that there are no
+ active MP objects that were allocated using the previously active
+ allocation function! Usually, that means that you have to call
+ this function before any other MP function.*
+
+ The functions you supply should fit the following declarations:
+
+ - Function: void * allocate_function (size_t ALLOC_SIZE)
+ This function should return a pointer to newly allocated space
+ with at least ALLOC_SIZE storage units.
+
+ - Function: void * reallocate_function (void *PTR, size_t OLD_SIZE,
+ size_t NEW_SIZE)
+ This function should return a pointer to newly allocated space of
+ at least NEW_SIZE storage units, after copying at least the first
+ OLD_SIZE storage units from PTR. It should also de-allocate the
+ space at PTR.
+
+ You can assume that the space at PTR was formerly returned from
+ `allocate_function' or `reallocate_function', for a request for
+ OLD_SIZE storage units.
+
+ - Function: void deallocate_function (void *PTR, size_t SIZE)
+ De-allocate the space pointed to by PTR.
+
+ You can assume that the space at PTR was formerly returned from
+ `allocate_function' or `reallocate_function', for a request for
+ SIZE storage units.
+
+ (A "storage unit" is the unit in which the `sizeof' operator returns
+the size of an object, normally an 8 bit byte.)
+
+
+File: gmp.info, Node: Contributors, Next: References, Prev: Custom Allocation, Up: Top
+
+Contributors
+************
+
+ I would like to thank Gunnar Sjoedin and Hans Riesel for their help
+with mathematical problems, Richard Stallman for his help with design
+issues and for revising the first version of this manual, Brian Beuning
+and Doug Lea for their testing of early versions of the library.
+
+ John Amanatides of York University in Canada contributed the function
+`mpz_probab_prime_p'.
+
+ Paul Zimmermann of Inria sparked the development of GMP 2, with his
+comparisons between bignum packages.
+
+ Ken Weber (Kent State University, Universidade Federal do Rio Grande
+do Sul) contributed `mpz_gcd', `mpz_divexact', `mpn_gcd', and
+`mpn_bdivmod', partially supported by CNPq (Brazil) grant 301314194-2.
+
+ Per Bothner of Cygnus Support helped to set up MP to use Cygnus'
+configure. He has also made valuable suggestions and tested numerous
+intermediary releases.
+
+ Joachim Hollman was involved in the design of the `mpf' interface,
+and in the `mpz' design revisions for version 2.
+
+ Bennet Yee contributed the functions `mpz_jacobi' and `mpz_legendre'.
+
+ Andreas Schwab contributed the files `mpn/m68k/lshift.S' and
+`mpn/m68k/rshift.S'.
+
+ The development of floating point functions of GNU MP 2, were
+supported in part by the ESPRIT-BRA (Basic Research Activities) 6846
+project POSSO (POlynomial System SOlving).
+
+ GNU MP 2 was finished and released by TMG Datakonsult,
+Sodermannagatan 5, 116 23 STOCKHOLM, SWEDEN, in cooperation with the
+IDA Center for Computing Sciences, USA.
+
+
+File: gmp.info, Node: References, Prev: Contributors, Up: Top
+
+References
+**********
+
+ * Donald E. Knuth, "The Art of Computer Programming", vol 2,
+ "Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+ * John D. Lipson, "Elements of Algebra and Algebraic Computing", The
+ Benjamin Cummings Publishing Company Inc, 1981.
+
+ * Richard M. Stallman, "Using and Porting GCC", Free Software
+ Foundation, 1995.
+
+ * Peter L. Montgomery, "Modular Multiplication Without Trial
+ Division", in Mathematics of Computation, volume 44, number 170,
+ April 1985.
+
+ * Torbjorn Granlund and Peter L. Montgomery, "Division by Invariant
+ Integers using Multiplication", in Proceedings of the SIGPLAN
+ PLDI'94 Conference, June 1994.
+
+ * Tudor Jebelean, "An algorithm for exact division", Journal of
+ Symbolic Computation, v. 15, 1993, pp. 169-180.
+
+ * Kenneth Weber, "The accelerated integer GCD algorithm", ACM
+ Transactions on Mathematical Software, v. 21 (March), 1995, pp.
+ 111-122.
+
+
+File: gmp.info, Node: Concept Index, Up: Top
+
+Concept Index
+*************
+
+* Menu:
+
+* gmp.h: MP Basics.
+* mp.h: BSD Compatible Functions.
+* Arithmetic functions <1>: Float Arithmetic.
+* Arithmetic functions: Integer Arithmetic.
+* Bit manipulation functions: Integer Logic and Bit Fiddling.
+* BSD MP compatible functions: BSD Compatible Functions.
+* Comparison functions: Float Comparison.
+* Conditions for copying GNU MP: Copying.
+* Conversion functions <1>: Converting Integers.
+* Conversion functions: Converting Floats.
+* Copying conditions: Copying.
+* Float arithmetic functions: Float Arithmetic.
+* Float assignment functions: Assigning Floats.
+* Float comparisons functions: Float Comparison.
+* Float functions: Floating-point Functions.
+* Float input and output functions: I/O of Floats.
+* Floating-point functions: Floating-point Functions.
+* Floating-point number: MP Basics.
+* I/O functions <1>: I/O of Floats.
+* I/O functions: I/O of Integers.
+* Initialization and assignment functions <1>: Simultaneous Float Init & Assign.
+* Initialization and assignment functions: Simultaneous Integer Init & Assign.
+* Input functions <1>: I/O of Integers.
+* Input functions: I/O of Floats.
+* Installation: Installing MP.
+* Integer: MP Basics.
+* Integer arithmetic functions: Integer Arithmetic.
+* Integer assignment functions: Assigning Integers.
+* Integer conversion functions: Converting Integers.
+* Integer functions: Integer Functions.
+* Integer input and output functions: I/O of Integers.
+* Limb: MP Basics.
+* Logical functions: Integer Logic and Bit Fiddling.
+* Low-level functions: Low-level Functions.
+* Miscellaneous float functions: Miscellaneous Float Functions.
+* Miscellaneous integer functions: Miscellaneous Integer Functions.
+* Output functions <1>: I/O of Floats.
+* Output functions: I/O of Integers.
+* Rational number: MP Basics.
+* Rational number functions: Rational Number Functions.
+* Reporting bugs: Reporting Bugs.
+* User-defined precision: Floating-point Functions.
+
diff --git a/gnu/lib/libgmp/gmp.info-3 b/gnu/lib/libgmp/gmp.info-3
new file mode 100644
index 0000000..a3020a7
--- /dev/null
+++ b/gnu/lib/libgmp/gmp.info-3
@@ -0,0 +1,259 @@
+This is Info file gmp.info, produced by Makeinfo-1.64 from the input
+file gmp.texi.
+
+START-INFO-DIR-ENTRY
+* gmp: (gmp.info). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+
+ This file documents GNU MP, a library for arbitrary-precision
+arithmetic.
+
+ Copyright (C) 1991, 1993, 1994, 1995, 1996 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 Foundation.
+
+
+File: gmp.info, Node: Function Index, Up: Top
+
+Function and Type Index
+***********************
+
+* Menu:
+
+* mp_limb_t: MP Basics.
+* mpf_t: MP Basics.
+* mpq_t: MP Basics.
+* mpz_t: MP Basics.
+* __GNU_MP_VERSION: MP Basics.
+* __GNU_MP_VERSION_MINOR: MP Basics.
+* _mpz_realloc: Initializing Integers.
+* allocate_function: Custom Allocation.
+* deallocate_function: Custom Allocation.
+* gcd: BSD Compatible Functions.
+* itom: BSD Compatible Functions.
+* madd: BSD Compatible Functions.
+* mcmp: BSD Compatible Functions.
+* mdiv: BSD Compatible Functions.
+* mfree: BSD Compatible Functions.
+* min: BSD Compatible Functions.
+* mout: BSD Compatible Functions.
+* move: BSD Compatible Functions.
+* mp_set_memory_functions: Custom Allocation.
+* mpf_abs: Float Arithmetic.
+* mpf_add: Float Arithmetic.
+* mpf_add_ui: Float Arithmetic.
+* mpf_clear: Initializing Floats.
+* mpf_cmp: Float Comparison.
+* mpf_cmp_si: Float Comparison.
+* mpf_cmp_ui: Float Comparison.
+* mpf_div: Float Arithmetic.
+* mpf_div_2exp: Float Arithmetic.
+* mpf_div_ui: Float Arithmetic.
+* mpf_eq: Float Comparison.
+* mpf_get_d: Converting Floats.
+* mpf_get_prec: Initializing Floats.
+* mpf_get_str: Converting Floats.
+* mpf_init: Initializing Floats.
+* mpf_init2: Initializing Floats.
+* mpf_init_set: Simultaneous Float Init & Assign.
+* mpf_init_set_d: Simultaneous Float Init & Assign.
+* mpf_init_set_si: Simultaneous Float Init & Assign.
+* mpf_init_set_str: Simultaneous Float Init & Assign.
+* mpf_init_set_ui: Simultaneous Float Init & Assign.
+* mpf_inp_str: I/O of Floats.
+* mpf_mul: Float Arithmetic.
+* mpf_mul_2exp: Float Arithmetic.
+* mpf_mul_ui: Float Arithmetic.
+* mpf_neg: Float Arithmetic.
+* mpf_out_str: I/O of Floats.
+* mpf_random2: Miscellaneous Float Functions.
+* mpf_reldiff: Float Comparison.
+* mpf_set: Assigning Floats.
+* mpf_set_d: Assigning Floats.
+* mpf_set_default_prec: Initializing Floats.
+* mpf_set_prec: Initializing Floats.
+* mpf_set_prec_raw: Initializing Floats.
+* mpf_set_q: Assigning Floats.
+* mpf_set_si: Assigning Floats.
+* mpf_set_str: Assigning Floats.
+* mpf_set_ui: Assigning Floats.
+* mpf_set_z: Assigning Floats.
+* mpf_sgn: Float Comparison.
+* mpf_sqrt: Float Arithmetic.
+* mpf_sqrt_ui: Float Arithmetic.
+* mpf_sub: Float Arithmetic.
+* mpf_sub_ui: Float Arithmetic.
+* mpf_ui_div: Float Arithmetic.
+* mpf_ui_sub: Float Arithmetic.
+* mpn_add: Low-level Functions.
+* mpn_add_1: Low-level Functions.
+* mpn_add_n: Low-level Functions.
+* mpn_addmul_1: Low-level Functions.
+* mpn_bdivmod: Low-level Functions.
+* mpn_cmp: Low-level Functions.
+* mpn_divmod: Low-level Functions.
+* mpn_divmod_1: Low-level Functions.
+* mpn_divrem: Low-level Functions.
+* mpn_divrem_1: Low-level Functions.
+* mpn_gcd: Low-level Functions.
+* mpn_gcd_1: Low-level Functions.
+* mpn_gcdext: Low-level Functions.
+* mpn_get_str: Low-level Functions.
+* mpn_hamdist: Low-level Functions.
+* mpn_lshift: Low-level Functions.
+* mpn_mod_1: Low-level Functions.
+* mpn_mul: Low-level Functions.
+* mpn_mul_1: Low-level Functions.
+* mpn_mul_n: Low-level Functions.
+* mpn_perfect_square_p: Low-level Functions.
+* mpn_popcount: Low-level Functions.
+* mpn_preinv_mod_1: Low-level Functions.
+* mpn_random2: Low-level Functions.
+* mpn_rshift: Low-level Functions.
+* mpn_scan0: Low-level Functions.
+* mpn_scan1: Low-level Functions.
+* mpn_set_str: Low-level Functions.
+* mpn_sqrtrem: Low-level Functions.
+* mpn_sub: Low-level Functions.
+* mpn_sub_1: Low-level Functions.
+* mpn_sub_n: Low-level Functions.
+* mpn_submul_1: Low-level Functions.
+* mpq_add: Assigning Rationals.
+* mpq_canonicalize: Rational Number Functions.
+* mpq_clear: Initializing Rationals.
+* mpq_cmp: Comparing Rationals.
+* mpq_cmp_ui: Comparing Rationals.
+* mpq_denref: Applying Integer Functions.
+* mpq_div: Assigning Rationals.
+* mpq_equal: Comparing Rationals.
+* mpq_get_d: Miscellaneous Rational Functions.
+* mpq_get_den: Miscellaneous Rational Functions.
+* mpq_get_num: Miscellaneous Rational Functions.
+* mpq_init: Initializing Rationals.
+* mpq_inv: Assigning Rationals.
+* mpq_mul: Assigning Rationals.
+* mpq_neg: Assigning Rationals.
+* mpq_numref: Applying Integer Functions.
+* mpq_set: Initializing Rationals.
+* mpq_set_den: Miscellaneous Rational Functions.
+* mpq_set_num: Miscellaneous Rational Functions.
+* mpq_set_si: Initializing Rationals.
+* mpq_set_ui: Initializing Rationals.
+* mpq_set_z: Initializing Rationals.
+* mpq_sgn: Comparing Rationals.
+* mpq_sub: Assigning Rationals.
+* mpz_abs: Integer Arithmetic.
+* mpz_add: Integer Arithmetic.
+* mpz_add_ui: Integer Arithmetic.
+* mpz_and: Integer Logic and Bit Fiddling.
+* mpz_array_init: Initializing Integers.
+* mpz_cdiv_q: Integer Arithmetic.
+* mpz_cdiv_q_ui: Integer Arithmetic.
+* mpz_cdiv_qr: Integer Arithmetic.
+* mpz_cdiv_qr_ui: Integer Arithmetic.
+* mpz_cdiv_r: Integer Arithmetic.
+* mpz_cdiv_r_ui: Integer Arithmetic.
+* mpz_cdiv_ui: Integer Arithmetic.
+* mpz_clear: Initializing Integers.
+* mpz_clrbit: Integer Logic and Bit Fiddling.
+* mpz_cmp: Comparison Functions.
+* mpz_cmp_si: Comparison Functions.
+* mpz_cmp_ui: Comparison Functions.
+* mpz_com: Integer Logic and Bit Fiddling.
+* mpz_divexact: Integer Arithmetic.
+* mpz_fac_ui: Integer Arithmetic.
+* mpz_fdiv_q: Integer Arithmetic.
+* mpz_fdiv_q_2exp: Integer Arithmetic.
+* mpz_fdiv_q_ui: Integer Arithmetic.
+* mpz_fdiv_qr: Integer Arithmetic.
+* mpz_fdiv_qr_ui: Integer Arithmetic.
+* mpz_fdiv_r: Integer Arithmetic.
+* mpz_fdiv_r_2exp: Integer Arithmetic.
+* mpz_fdiv_r_ui: Integer Arithmetic.
+* mpz_fdiv_ui: Integer Arithmetic.
+* mpz_gcd: Integer Arithmetic.
+* mpz_gcd_ui: Integer Arithmetic.
+* mpz_gcdext: Integer Arithmetic.
+* mpz_get_d: Converting Integers.
+* mpz_get_si: Converting Integers.
+* mpz_get_str: Converting Integers.
+* mpz_get_ui: Converting Integers.
+* mpz_hamdist: Integer Logic and Bit Fiddling.
+* mpz_init: Initializing Integers.
+* mpz_init_set: Simultaneous Integer Init & Assign.
+* mpz_init_set_d: Simultaneous Integer Init & Assign.
+* mpz_init_set_si: Simultaneous Integer Init & Assign.
+* mpz_init_set_str: Simultaneous Integer Init & Assign.
+* mpz_init_set_ui: Simultaneous Integer Init & Assign.
+* mpz_inp_raw: I/O of Integers.
+* mpz_inp_str: I/O of Integers.
+* mpz_invert: Integer Arithmetic.
+* mpz_ior: Integer Logic and Bit Fiddling.
+* mpz_jacobi: Integer Arithmetic.
+* mpz_legendre: Integer Arithmetic.
+* mpz_mod: Integer Arithmetic.
+* mpz_mod_ui: Integer Arithmetic.
+* mpz_mul: Integer Arithmetic.
+* mpz_mul_2exp: Integer Arithmetic.
+* mpz_mul_ui: Integer Arithmetic.
+* mpz_neg: Integer Arithmetic.
+* mpz_out_raw: I/O of Integers.
+* mpz_out_str: I/O of Integers.
+* mpz_perfect_square_p: Integer Arithmetic.
+* mpz_popcount: Integer Logic and Bit Fiddling.
+* mpz_pow_ui: Integer Arithmetic.
+* mpz_powm: Integer Arithmetic.
+* mpz_powm_ui: Integer Arithmetic.
+* mpz_probab_prime_p: Integer Arithmetic.
+* mpz_random: Miscellaneous Integer Functions.
+* mpz_random2: Miscellaneous Integer Functions.
+* mpz_scan0: Integer Logic and Bit Fiddling.
+* mpz_scan1: Integer Logic and Bit Fiddling.
+* mpz_set: Assigning Integers.
+* mpz_set_d: Assigning Integers.
+* mpz_set_f: Assigning Integers.
+* mpz_set_q: Assigning Integers.
+* mpz_set_si: Assigning Integers.
+* mpz_set_str: Assigning Integers.
+* mpz_set_ui: Assigning Integers.
+* mpz_setbit: Integer Logic and Bit Fiddling.
+* mpz_sgn: Comparison Functions.
+* mpz_size: Miscellaneous Integer Functions.
+* mpz_sizeinbase: Miscellaneous Integer Functions.
+* mpz_sqrt: Integer Arithmetic.
+* mpz_sqrtrem: Integer Arithmetic.
+* mpz_sub: Integer Arithmetic.
+* mpz_sub_ui: Integer Arithmetic.
+* mpz_tdiv_q: Integer Arithmetic.
+* mpz_tdiv_q_2exp: Integer Arithmetic.
+* mpz_tdiv_q_ui: Integer Arithmetic.
+* mpz_tdiv_qr: Integer Arithmetic.
+* mpz_tdiv_qr_ui: Integer Arithmetic.
+* mpz_tdiv_r: Integer Arithmetic.
+* mpz_tdiv_r_2exp: Integer Arithmetic.
+* mpz_tdiv_r_ui: Integer Arithmetic.
+* mpz_ui_pow_ui: Integer Arithmetic.
+* msqrt: BSD Compatible Functions.
+* msub: BSD Compatible Functions.
+* mtox: BSD Compatible Functions.
+* mult: BSD Compatible Functions.
+* pow: BSD Compatible Functions.
+* reallocate_function: Custom Allocation.
+* rpow: BSD Compatible Functions.
+* sdiv: BSD Compatible Functions.
+* xtom: BSD Compatible Functions.
+
+
diff --git a/gnu/lib/libgmp/gmp.texi b/gnu/lib/libgmp/gmp.texi
new file mode 100644
index 0000000..7e6884e
--- /dev/null
+++ b/gnu/lib/libgmp/gmp.texi
@@ -0,0 +1,2697 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gmp.info
+@settitle GNU MP 2.0.2
+@synindex tp fn
+@iftex
+@afourpaper
+@end iftex
+@comment %**end of header
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* gmp: (gmp.info). GNU Multiple Precision Arithmetic Library.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@c smallbook
+
+@iftex
+@finalout
+@end iftex
+
+@c Note: the edition number is listed in *three* places; please update
+@c all three. Also, update the month and year where appropriate.
+
+@c ==> Update edition number for settitle and subtitle, and in the
+@c ==> following paragraph; update date, too.
+
+
+@ifinfo
+This file documents GNU MP, a library for arbitrary-precision arithmetic.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 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 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
+
+@setchapternewpage on
+@titlepage
+@c use the new format for titles
+
+@title GNU MP
+@subtitle The GNU Multiple Precision Arithmetic Library
+@subtitle Edition 2.0.2
+@subtitle June 1996
+
+@author by Torbj@"orn Granlund, TMG Datakonsult
+
+@c Include the Distribution inside the titlepage so
+@c that headings are turned off.
+
+@tex
+\global\parindent=0pt
+\global\parskip=8pt
+\global\baselineskip=13pt
+@end tex
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+@sp 2
+
+Published by the Free Software Foundation @*
+59 Temple Place - Suite 330 @*
+Boston, MA 02111-1307, 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 Foundation.
+@end titlepage
+@headings double
+
+@ifinfo
+@node Top, Copying, (dir), (dir)
+
+@top GNU MP
+
+This manual documents how to install and use the GNU multiple precision
+arithmetic library, version 2.0.2.
+
+@end ifinfo
+
+@menu
+* Copying:: GMP Copying Conditions (LGPL).
+* Introduction to MP:: Brief introduction to GNU MP.
+* Installing MP:: How to configure and compile the MP library.
+* MP Basics:: What every MP user should now.
+* Reporting Bugs:: How to usefully report bugs.
+* Integer Functions:: Functions for arithmetic on signed integers.
+* Rational Number Functions:: Functions for arithmetic on rational numbers.
+* Floating-point Functions:: Functions for arithmetic on floats.
+* Low-level Functions:: Fast functions for natural numbers.
+* BSD Compatible Functions:: All functions found in BSD MP.
+* Custom Allocation:: How to customize the internal allocation.
+
+* Contributors::
+* References::
+* Concept Index::
+* Function Index::
+@end menu
+
+@node Copying, Introduction to MP, Top, Top
+@comment node-name, next, previous, up
+@unnumbered GNU MP Copying Conditions
+@cindex Copying conditions
+@cindex Conditions for copying GNU MP
+
+This library is @dfn{free}; this means that everyone is free to use it and
+free to redistribute it on a free basis. The library is not in the public
+domain; it is copyrighted and there are restrictions on its distribution, but
+these restrictions are designed to permit everything that a good cooperating
+citizen would want to do. What is not allowed is to try to prevent others
+from further sharing any version of this library that they might get from
+you.@refill
+
+Specifically, we want to make sure that you have the right to give away copies
+of the library, that you receive source code or else can get it if you want
+it, that you can change this library or use pieces of it in new free programs,
+and that you know you can do these things.@refill
+
+To make sure that everyone has such rights, we have to forbid you to deprive
+anyone else of these rights. For example, if you distribute copies of the GNU
+MP library, 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 tell them their rights.@refill
+
+Also, for our own protection, we must make certain that everyone finds out
+that there is no warranty for the GNU MP library. If it is modified by
+someone else and passed on, we want their recipients to know that what they
+have is not what we distributed, so that any problems introduced by others
+will not reflect on our reputation.@refill
+
+The precise conditions of the license for the GNU MP library are found in the
+Library General Public License that accompany the source code.@refill
+
+@node Introduction to MP, Installing MP, Copying, Top
+@comment node-name, next, previous, up
+@chapter Introduction to GNU MP
+
+
+GNU MP is a portable library written in C for arbitrary precision arithmetic
+on integers, rational numbers, and floating-point numbers. It aims to provide
+the fastest possible arithmetic for all applications that need higher
+precision than is directly supported by the basic C types.
+
+Many applications use just a few hundred bits of precision; but some
+applications may need thousands or even millions of bits. MP is designed to
+give good performance for both, by choosing algorithms based on the sizes of
+the operands, and by carefully keeping the overhead at a minimum.
+
+The speed of MP is achieved by using fullwords as the basic arithmetic type,
+by using sophisticated algorithms, by including carefully optimized assembly
+code for the most common inner loops for many different CPUs, and by a general
+emphasis on speed (as opposed to simplicity or elegance).
+
+There is carefully optimized assembly code for these CPUs: DEC Alpha, Amd
+29000, HPPA 1.0 and 1.1, Intel Pentium and generic x86, Intel i960, Motorola
+MC68000, MC68020, MC88100, and MC88110, Motorola/IBM PowerPC, National
+NS32000, IBM POWER, MIPS R3000, R4000, SPARCv7, SuperSPARC, generic SPARCv8,
+and DEC VAX. Some optimizations also for ARM, Clipper, IBM ROMP (RT), and
+Pyramid AP/XP.
+
+This version of MP is released under a more liberal license than previous
+versions. It is now permitted to link MP to non-free programs, as long as MP
+source code is provided when distributing the non-free program.
+
+
+@section How to use this Manual
+
+Everyone should read @ref{MP Basics}. If you need to install the library
+yourself, you need to read @ref{Installing MP}, too.
+
+The rest of the manual can be used for later reference, although it is
+probably a good idea to glance through it.
+
+
+@node Installing MP, MP Basics, Introduction to MP, Top
+@comment node-name, next, previous, up
+@chapter Installing MP
+@cindex Installation
+
+To build MP, you first have to configure it for your CPU and operating system.
+You need a C compiler, preferably GCC, but any reasonable compiler should
+work. And you need a standard Unix @samp{make} program, plus some other
+standard Unix utility programs.
+
+(If you're on an MS-DOS machine, your can build MP using @file{make.bat}. It
+requires that djgpp is installed. It does not require configuration, nor is
+@samp{make} needed; @file{make.bat} both configures and builds the library.)
+
+Here are the steps needed to install the library on Unix systems:
+
+@enumerate
+@item
+In most cases, @samp{./configure --target=cpu-vendor-os}, should work both for
+native and cross-compilation. If you get error messages, your machine might
+not be supported.
+
+If you want to compile in a separate object directory, cd to that directory,
+and prefix the configure command with the path to the MP source directory.
+Not all @samp{make} programs have the necessary features to support this. In
+particular, SunOS and Slowaris @samp{make} have bugs that makes them unable to
+build from a separate object directory. Use GNU @samp{make} instead.
+
+In addition to the standard cpu-vendor-os tuples, MP recognizes sparc8 and
+supersparc as valid CPU names. Specifying these CPU names for relevant
+systems will improve performance significantly.
+
+In general, if you want a library that runs as fast as possible, you should
+make sure you configure MP for the exact CPU type your system uses.
+
+If you have @code{gcc} in your @code{PATH}, it will be used by default. To
+override this, pass @samp{-with-gcc=no} to @file{configure}.
+
+@item
+@samp{make}
+
+This will compile MP, and create a library archive file @file{libgmp.a} in the
+working directory.
+
+@item
+@samp{make check}
+
+This will make sure MP was built correctly. If you get error messages, please
+report this to @samp{bug-gmp@@prep.ai.mit.edu}. (@xref{Reporting Bugs}, for
+information on what to include in useful bug reports.)
+
+@item
+@samp{make install}
+
+This will copy the file @file{gmp.h} and @file{libgmp.a}, as well as the info
+files, to @file{/usr/local} (or if you passed the @samp{--prefix} option to
+@file{configure}, to the directory given as argument to @samp{--prefix}).
+@end enumerate
+
+@noindent
+If you wish to build and install the BSD MP compatible functions, use
+@samp{make libmp.a} and @samp{make install-bsdmp}.
+
+There are some other useful make targets:
+
+@itemize @bullet
+@item
+@samp{doc}
+
+Create a DVI version of the manual, in @file{gmp.dvi} and a set of info files,
+in @file{gmp.info}, @file{gmp.info-1}, @file{gmp.info-2}, etc.
+
+@item
+@samp{ps}
+
+Create a Postscript version of the manual, in @file{gmp.ps}.
+
+@item
+@samp{html}
+
+Create a HTML version of the manual, in @file{gmp.html}.
+
+@item
+@samp{clean}
+
+Delete all object files and archive files, but not the configuration files.
+
+@item
+@samp{distclean}
+
+Delete all files not included in the distribution.
+
+@item
+@samp{uninstall}
+
+Delete all files copied by @samp{make install}.
+@end itemize
+
+
+@section Known Build Problems
+
+GCC 2.7.2 (as well as 2.6.3) for the RS/6000 and PowerPC can not be used to
+compile MP, due to a bug in GCC. If you want to use GCC for these machines,
+you need to apply the patch below to GCC, or use a later version of the
+compiler.
+
+If you are on a Sequent Symmetry, use the GNU assembler instead of the
+system's assembler, since the latter has serious bugs.
+
+The system compiler on NeXT is a massacred and old gcc, even if the compiler
+calls itself @file{cc}. This compiler cannot be used to build MP. You need
+to get a real gcc, and install that before you compile MP. (NeXT might have
+fixed this in newer releases of their system.)
+
+The system C compiler under SunOS 4 has a bug that makes it miscompile
+mpq/get_d.c. This will make @samp{make check} fail.
+
+Please report other problems to @samp{bug-gmp@@prep.ai.mit.edu}.
+@xref{Reporting Bugs}.
+
+
+Patch to apply to GCC 2.6.3 and 2.7.2:
+
+@example
+*** config/rs6000/rs6000.md Sun Feb 11 08:22:11 1996
+--- config/rs6000/rs6000.md.new Sun Feb 18 03:33:37 1996
+***************
+*** 920,926 ****
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+! "nor. %0,%2,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
+--- 920,926 ----
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (not:SI (match_dup 1)))]
+ ""
+! "nor. %0,%1,%1"
+ [(set_attr "type" "compare")])
+
+ (define_insn ""
+@end example
+
+@node MP Basics, Reporting Bugs, Installing MP, Top
+@comment node-name, next, previous, up
+@chapter MP Basics
+
+
+@cindex @file{gmp.h}
+All declarations needed to use MP are collected in the include file
+@file{gmp.h}. It is designed to work with both C and C++ compilers.
+
+
+@section Nomenclature and Types
+
+@cindex Integer
+@tindex @code{mpz_t}
+@noindent
+In this manual, @dfn{integer} usually means a multiple precision integer, as
+defined by the MP library. The C data type for such integers is @code{mpz_t}.
+Here are some examples of how to declare such integers:
+
+@example
+mpz_t sum;
+
+struct foo @{ mpz_t x, y; @};
+
+mpz_t vec[20];
+@end example
+
+@cindex Rational number
+@tindex @code{mpq_t}
+@noindent
+@dfn{Rational number} means a multiple precision fraction. The C data type
+for these fractions is @code{mpq_t}. For example:
+
+@example
+mpq_t quotient;
+@end example
+
+@cindex Floating-point number
+@tindex @code{mpf_t}
+@noindent
+@dfn{Floating point number} or @dfn{Float} for short, is an arbitrary precision
+mantissa with an limited precision exponent. The C data type for such objects
+is @code{mpf_t}.
+
+@cindex Limb
+@tindex @code{mp_limb_t}
+@noindent
+A @dfn{limb} means the part of a multi-precision number that fits in a single
+word. (We chose this word because a limb of the human body is analogous to a
+digit, only larger, and containing several digits.) Normally a limb contains
+32 or 64 bits. The C data type for a limb is @code{mp_limb_t}.
+
+
+@section Function Classes
+
+There are six classes of functions in the MP library:
+
+@enumerate
+@item
+Functions for signed integer arithmetic, with names beginning with
+@code{mpz_}. The associated type is @code{mpz_t}. There are about 100
+functions in this class.
+
+@item
+Functions for rational number arithmetic, with names beginning with
+@code{mpq_}. The associated type is @code{mpq_t}. There are about 20
+functions in this class, but the functions in the previous class can be used
+for performing arithmetic on the numerator and denominator separately.
+
+@item
+Functions for floating-point arithmetic, with names beginning with
+@code{mpf_}. The associated type is @code{mpf_t}. There are about 50
+functions is this class.
+
+@item
+Functions compatible with Berkeley MP, such as @code{itom}, @code{madd}, and
+@code{mult}. The associated type is @code{MINT}.
+
+@item
+Fast low-level functions that operate on natural numbers. These are used by
+the functions in the preceding groups, and you can also call them directly
+from very time-critical user programs. These functions' names begin with
+@code{mpn_}. There are about 30 (hard-to-use) functions in this class.
+
+The associated type is array of @code{mp_limb_t}.
+
+@item
+Miscellaneous functions. Functions for setting up custom allocation.
+@end enumerate
+
+
+@section MP Variable Conventions
+
+As a general rule, all MP functions expect output arguments before input
+arguments. This notation is based on an analogy with the assignment operator.
+(The BSD MP compatibility functions disobey this rule, having the output
+argument(s) last.)
+
+MP allows you to use the same variable for both input and output in the same
+expression. For example, the main function for integer multiplication,
+@code{mpz_mul}, can be used like this: @code{mpz_mul (x, x, x)}. This
+computes the square of @var{x} and puts the result back in @var{x}.
+
+Before you can assign to an MP variable, you need to initialize it by calling
+one of the special initialization functions. When you're done with a
+variable, you need to clear it out, using one of the functions for that
+purpose. Which function to use depends on the type of variable. See the
+chapters on integer functions, rational number functions, and floating-point
+functions for details.
+
+A variable should only be initialized once, or at least cleared out between
+each initialization. After a variable has been initialized, it may be
+assigned to any number of times.
+
+For efficiency reasons, avoid to initialize and clear out a variable in loops.
+Instead, initialize it before entering the loop, and clear it out after the
+loop has exited.
+
+You don't need to be concerned about allocating additional space for MP
+variables. All functions in MP automatically allocate additional space when a
+variable does not already have enough space. They do not, however, reduce the
+space when a smaller number is stored in the object. Most of the time, this
+policy is best, since it avoids frequent re-allocation.
+
+
+@section Useful Macros and Constants
+
+@deftypevr {Global Constant} {const int} mp_bits_per_limb
+The number of bits per limb.
+@end deftypevr
+
+@defmac __GNU_MP_VERSION
+@defmacx __GNU_MP_VERSION_MINOR
+The major and minor MP version, respectively, as integers.
+@end defmac
+
+@section Compatibility with Version 1.x
+
+This version of MP is upward compatible with previous versions of MP, with a
+few exceptions.
+
+@enumerate
+@item Integer division functions round the result differently. The old
+functions (@code{mpz_div}, @code{mpz_divmod}, @code{mpz_mdiv},
+@code{mpz_mdivmod}, etc) now all use floor rounding (i.e., they round the
+quotient to @minus{}infinity). There are a lot of new functions for integer
+division, giving the user better control over the rounding.
+
+@item The function @code{mpz_mod} now compute the true @strong{mod} function.
+
+@item The functions @code{mpz_powm} and @code{mpz_powm_ui} now use
+@strong{mod} for reduction.
+
+@item The assignment functions for rational numbers do no longer canonicalize
+their results. In the case a non-canonical result could arise from an
+assignment, the user need to insert an explicit call to
+@code{mpq_canonicalize}. This change was made for efficiency.
+
+@item Output generated by @code{mpz_out_raw} in this release cannot be read
+by @code{mpz_inp_raw} in previous releases. This change was made for making
+the file format truly portable between machines with different word sizes.
+
+@item Several @code{mpn} functions have changed. But they were intentionally
+undocumented in previous releases.
+
+@item The functions @code{mpz_cmp_ui}, @code{mpz_cmp_si}, and @code{mpq_cmp_ui}
+are now implementated as macros, and thereby sometimes evaluate their
+arguments multiple times.
+
+@item The functions @code{mpz_pow_ui} and @code{mpz_ui_pow_ui} now yield 1
+for 0^0. (In version 1, they yielded 0.)
+
+@end enumerate
+
+
+@section Getting the Latest Version of MP
+
+The latest version of the MP library is available by anonymous ftp from
+from @samp{prep.ai.mit.edu}. The file name is
+@file{/pub/gnu/gmp-M.N.tar.gz}. Many sites around the world mirror
+@samp{prep}; please use a mirror site near you.
+
+@node Reporting Bugs, Integer Functions, MP Basics, Top
+@comment node-name, next, previous, up
+@chapter Reporting Bugs
+@cindex Reporting bugs
+
+If you think you have found a bug in the MP library, please investigate it and
+report it. We have made this library available to you, and it is not to ask
+too much from you, to ask you to report the bugs that you find.
+
+There are a few things you should think about when you put your bug report
+together.
+
+You have to send us a test case that makes it possible for us to reproduce the
+bug. Include instructions on how to run the test case.
+
+You also have to explain what is wrong; if you get a crash, or if the results
+printed are incorrect and in that case, in what way.
+
+It is not uncommon that an observed problem is actually due to a bug in the
+compiler used when building MP; the MP code tends to explore interesting
+corners in compilers. Therefore, please include compiler version information
+in your bug report. This can be extracted using @samp{what `which cc`}, or,
+if you're using gcc, @samp{gcc -v}. Also, include the output from @samp{uname
+-a}.
+
+If your bug report is good, we will do our best to help you to get a corrected
+version of the library; if the bug report is poor, we won't do anything about
+it (aside of chiding you to send better bug reports).
+
+Send your bug report to: @samp{bug-gmp@@prep.ai.mit.edu}.
+
+If you think something in this manual is unclear, or downright incorrect, or if
+the language needs to be improved, please send a note to the same address.
+
+
+@node Integer Functions, Rational Number Functions, Reporting Bugs, Top
+@comment node-name, next, previous, up
+@chapter Integer Functions
+@cindex Integer functions
+
+This chapter describes the MP functions for performing integer arithmetic.
+These functions start with the prefix @code{mpz_}.
+
+Arbitrary precision integers are stored in objects of type @code{mpz_t}.
+
+@menu
+* Initializing Integers::
+* Assigning Integers::
+* Simultaneous Integer Init & Assign::
+* Converting Integers::
+* Integer Arithmetic::
+* Comparison Functions::
+* Integer Logic and Bit Fiddling::
+* I/O of Integers::
+* Miscellaneous Integer Functions::
+@end menu
+
+@node Initializing Integers, Assigning Integers, , Integer Functions
+@comment node-name, next, previous, up
+@section Initialization and Assignment Functions
+
+The functions for integer arithmetic assume that all integer objects are
+initialized. You do that by calling the function @code{mpz_init}.
+
+@deftypefun void mpz_init (mpz_t @var{integer})
+Initialize @var{integer} with limb space and set the initial numeric value to
+0. Each variable should normally only be initialized once, or at least cleared
+out (using @code{mpz_clear}) between each initialization.
+@end deftypefun
+
+Here is an example of using @code{mpz_init}:
+
+@example
+@{
+ mpz_t integ;
+ mpz_init (integ);
+ @dots{}
+ mpz_add (integ, @dots{});
+ @dots{}
+ mpz_sub (integ, @dots{});
+
+ /* Unless the program is about to exit, do ... */
+ mpz_clear (integ);
+@}
+@end example
+
+@noindent
+As you can see, you can store new values any number of times, once an
+object is initialized.
+
+@deftypefun void mpz_clear (mpz_t @var{integer})
+Free the limb space occupied by @var{integer}. Make sure to call this
+function for all @code{mpz_t} variables when you are done with them.
+@end deftypefun
+
+@deftypefun {void *} _mpz_realloc (mpz_t @var{integer}, mp_size_t @var{new_alloc})
+Change the limb space allocation to @var{new_alloc} limbs. This function is
+not normally called from user code, but it can be used to give memory back to
+the heap, or to increase the space of a variable to avoid repeated automatic
+re-allocation.
+@end deftypefun
+
+@deftypefun void mpz_array_init (mpz_t @var{integer_array}[], size_t @var{array_size}, mp_size_t @var{fixed_num_bits})
+Allocate @strong{fixed} limb space for all @var{array_size} integers in
+@var{integer_array}. The fixed allocation for each integer in the array is
+enough to store @var{fixed_num_bits}. If the fixed space will be insufficient
+for storing the result of a subsequent calculation, the result is
+unpredictable.
+
+This function is useful for decreasing the working set for some algorithms
+that use large integer arrays.
+
+There is no way to de-allocate the storage allocated by this function.
+Don't call @code{mpz_clear}!
+@end deftypefun
+
+
+@node Assigning Integers, Simultaneous Integer Init & Assign, Initializing Integers, Integer Functions
+@comment node-name, next, previous, up
+@subsection Assignment Functions
+@cindex Integer assignment functions
+
+These functions assign new values to already initialized integers
+(@pxref{Initializing Integers}).
+
+@deftypefun void mpz_set (mpz_t @var{rop}, mpz_t @var{op})
+@deftypefunx void mpz_set_ui (mpz_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpz_set_si (mpz_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpz_set_d (mpz_t @var{rop}, double @var{op})
+@deftypefunx void mpz_set_q (mpz_t @var{rop}, mpq_t @var{op})
+@deftypefunx void mpz_set_f (mpz_t @var{rop}, mpf_t @var{op})
+Set the value of @var{rop} from @var{op}.
+@end deftypefun
+
+@deftypefun int mpz_set_str (mpz_t @var{rop}, char *@var{str}, int @var{base})
+Set the value of @var{rop} from @var{str}, a '\0'-terminated C string in base
+@var{base}. White space is allowed in the string, and is simply ignored. The
+base may vary from 2 to 36. If @var{base} is 0, the actual base is determined
+from the leading characters: if the first two characters are `0x' or `0X',
+hexadecimal is assumed, otherwise if the first character is `0', octal is
+assumed, otherwise decimal is assumed.
+
+This function returns 0 if the entire string up to the '\0' is a valid
+number in base @var{base}. Otherwise it returns @minus{}1.
+@end deftypefun
+
+
+@node Simultaneous Integer Init & Assign, Converting Integers, Assigning Integers, Integer Functions
+@comment node-name, next, previous, up
+@subsection Combined Initialization and Assignment Functions
+@cindex Initialization and assignment functions
+
+For convenience, MP provides a parallel series of initialize-and-set functions
+which initialize the output and then store the value there. These functions'
+names have the form @code{mpz_init_set@dots{}}
+
+Here is an example of using one:
+
+@example
+@{
+ mpz_t pie;
+ mpz_init_set_str (pie, "3141592653589793238462643383279502884", 10);
+ @dots{}
+ mpz_sub (pie, @dots{});
+ @dots{}
+ mpz_clear (pie);
+@}
+@end example
+
+@noindent
+Once the integer has been initialized by any of the @code{mpz_init_set@dots{}}
+functions, it can be used as the source or destination operand for the ordinary
+integer functions. Don't use an initialize-and-set function on a variable
+already initialized!
+
+@deftypefun void mpz_init_set (mpz_t @var{rop}, mpz_t @var{op})
+@deftypefunx void mpz_init_set_ui (mpz_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpz_init_set_si (mpz_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpz_init_set_d (mpz_t @var{rop}, double @var{op})
+Initialize @var{rop} with limb space and set the initial numeric value from
+@var{op}.
+@end deftypefun
+
+@deftypefun int mpz_init_set_str (mpz_t @var{rop}, char *@var{str}, int @var{base})
+Initialize @var{rop} and set its value like @code{mpz_set_str} (see its
+documentation above for details).
+
+If the string is a correct base @var{base} number, the function returns 0;
+if an error occurs it returns @minus{}1. @var{rop} is initialized even if
+an error occurs. (I.e., you have to call @code{mpz_clear} for it.)
+@end deftypefun
+
+
+@node Converting Integers, Integer Arithmetic, Simultaneous Integer Init & Assign, Integer Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Integer conversion functions
+@cindex Conversion functions
+
+This section describes functions for converting arbitrary precision integers
+to standard C types. Functions for converting @emph{to} arbitrary
+precision integers are described in @ref{Assigning Integers} and @ref{I/O of
+Integers}.
+
+@deftypefun {unsigned long int} mpz_get_ui (mpz_t @var{op})
+Return the least significant part from @var{op}. This function combined
+with @* @code{mpz_tdiv_q_2exp(@dots{}, @var{op}, CHAR_BIT*sizeof(unsigned
+long int))} can be used to extract the limbs of an integer.
+@end deftypefun
+
+@deftypefun {signed long int} mpz_get_si (mpz_t @var{op})
+If @var{op} fits into a @code{signed long int} return the value of @var{op}.
+Otherwise return the least significant part of @var{op}, with the same sign
+as @var{op}.
+
+If @var{op} is too large to fit in a @code{signed long int}, the returned
+result is probably not very useful. @c To find out if the value will fit, use
+@c the function @code{mpz_fits_si}.
+@end deftypefun
+
+@deftypefun double mpz_get_d (mpz_t @var{op})
+Convert @var{op} to a double.
+@end deftypefun
+
+@deftypefun {char *} mpz_get_str (char *@var{str}, int @var{base}, mpz_t @var{op})
+Convert @var{op} to a string of digits in base @var{base}. The base may vary
+from 2 to 36.
+
+If @var{str} is NULL, space for the result string is allocated using the
+default allocation function, and a pointer to the string is returned.
+
+If @var{str} is not NULL, it should point to a block of storage enough large
+for the result. To find out the right amount of space to provide for
+@var{str}, use @code{mpz_sizeinbase (@var{op}, @var{base}) + 2}. The two
+extra bytes are for a possible minus sign, and for the terminating null
+character.
+@end deftypefun
+
+
+@node Integer Arithmetic, Comparison Functions, Converting Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+@cindex Integer arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpz_add (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_add_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} + @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} + @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_sub (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_sub_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @var{op1} @minus{} @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_mul (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_mul_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} times @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_mul_2exp (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} times 2 raised to @var{op2}. This operation can
+also be defined as a left shift, @var{op2} steps.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times 2^{op2}$. This operation can also be
+defined as a left shift, @var{op2} steps.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_neg (mpz_t @var{rop}, mpz_t @var{op})
+Set @var{rop} to @minus{}@var{op}.
+@end deftypefun
+
+@deftypefun void mpz_abs (mpz_t @var{rop}, mpz_t @var{op})
+Set @var{rop} to the absolute value of @var{op}.
+@end deftypefun
+
+@deftypefun void mpz_fac_ui (mpz_t @var{rop}, unsigned long int @var{op})
+Set @var{rop} to @var{op}!, the factorial of @var{op}.
+@end deftypefun
+
+@subsection Division functions
+
+Division is undefined if the divisor is zero, and passing a zero divisor to
+the divide or modulo functions, as well passing a zero mod argument to the
+@code{mpz_powm} and @code{mpz_powm_ui} functions, will make these functions
+intentionally divide by zero. This gives the user the possibility to handle
+arithmetic exceptions in these functions in the same manner as other
+arithmetic exceptions.
+
+There are three main groups of division functions:
+@itemize @bullet
+@item
+Functions that truncate the quotient towards 0. The names of these
+functions start with @code{mpz_tdiv}. The @samp{t} in the name is short for
+@samp{truncate}.
+@item
+Functions that round the quotient towards @minus{}infinity. The names of
+these routines start with @code{mpz_fdiv}. The @samp{f} in the name is
+short for @samp{floor}.
+@item
+Functions that round the quotient towards +infinity. The names of
+these routines start with @code{mpz_cdiv}. The @samp{c} in the name is
+short for @samp{ceil}.
+@end itemize
+
+For each rounding mode, there are a couple of variants. Here @samp{q} means
+that the quotient is computed, while @samp{r} means that the remainder is
+computed. Functions that compute both the quotient and remainder have
+@samp{qr} in the name.
+
+@deftypefun void mpz_tdiv_q (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_tdiv_q_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to [@var{op1}/@var{op2}]. The quotient is truncated towards
+0.
+@end deftypefun
+
+@deftypefun void mpz_tdiv_r (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_tdiv_r_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to (@var{op1} - [@var{op1}/@var{op2}] * @var{op2}).
+Unless the remainder is zero, it has the same sign as the dividend.
+@end deftypefun
+
+@deftypefun void mpz_tdiv_qr (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_tdiv_qr_ui (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, unsigned long int @var{op2})
+Divide @var{op1} by @var{op2} and put the quotient in @var{rop1} and the
+remainder in @var{rop2}. The quotient is rounded towards 0. Unless the
+remainder is zero, it has the same sign as the dividend.
+
+If @var{rop1} and @var{rop2} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun void mpz_fdiv_q (mpz_t @var{rop1}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_fdiv_q_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1}/@var{op2}. The quotient is rounded towards
+@minus{}infinity.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\lfloor@var{op1}/@var{op2}\rfloor$. (I.e., round
+the quotient towards $-\infty$.)
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_fdiv_r (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx {unsigned long int} mpz_fdiv_r_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Divide @var{op1} by @var{op2} and put the remainder in @var{rop}. Unless
+the remainder is zero, it has the same sign as the divisor.
+
+For @code{mpz_fdiv_r_ui} the remainder is small enough to fit in an
+@code{unsigned long int}, and is therefore returned.
+@end deftypefun
+
+@deftypefun void mpz_fdiv_qr (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx {unsigned long int} mpz_fdiv_qr_ui (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, unsigned long int @var{op2})
+Divide @var{op1} by @var{op2} and put the quotient in @var{rop1} and the
+remainder in @var{rop2}. The quotient is rounded towards @minus{}infinity.
+Unless the remainder is zero, it has the same sign as the divisor.
+
+For @code{mpz_fdiv_qr_ui} the remainder is small enough to fit in an
+@code{unsigned long int}, and is therefore returned.
+
+If @var{rop1} and @var{rop2} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_fdiv_ui (mpz_t @var{op1}, unsigned long int @var{op2})
+This function is similar to @code{mpz_fdiv_r_ui}, but the remainder is only
+returned; it is not stored anywhere.
+@end deftypefun
+
+@deftypefun void mpz_cdiv_q (mpz_t @var{rop1}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx void mpz_cdiv_q_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1}/@var{op2}. The quotient is rounded towards
++infinity.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\lceil@var{op1}/@var{op2}\rceil$. (I.e., round the
+quotient towards $+\infty$.)
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_cdiv_r (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx {unsigned long int} mpz_cdiv_r_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Divide @var{op1} by @var{op2} and put the remainder in @var{rop}. Unless
+the remainder is zero, it has the opposite sign as the divisor.
+
+For @code{mpz_cdiv_r_ui} the negated remainder is small enough to fit in an
+@code{unsigned long int}, and it is therefore returned.
+@end deftypefun
+
+@deftypefun void mpz_cdiv_qr (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx {unsigned long int} mpz_cdiv_qr_ui (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op1}, unsigned long int @var{op2})
+Divide @var{op1} by @var{op2} and put the quotient in @var{rop1} and the
+remainder in @var{rop2}. The quotient is rounded towards +infinity. Unless
+the remainder is zero, it has the opposite sign as the divisor.
+
+For @code{mpz_cdiv_qr_ui} the negated remainder is small enough to fit in an
+@code{unsigned long int}, and it is therefore returned.
+
+If @var{rop1} and @var{rop2} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_cdiv_ui (mpz_t @var{op1}, unsigned long int @var{op2})
+Return the negated remainder, similar to @code{mpz_cdiv_r_ui}. (The
+difference is that this function doesn't store the remainder anywhere.)
+@end deftypefun
+
+@deftypefun void mpz_mod (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx {unsigned long int} mpz_mod_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @var{op1} @code{mod} @var{op2}. The sign of the divisor is
+ignored, and the result is always non-negative.
+
+For @code{mpz_mod_ui} the remainder is small enough to fit in an
+@code{unsigned long int}, and is therefore returned.
+@end deftypefun
+
+@deftypefun void mpz_divexact (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+Set @var{rop} to @var{op1}/@var{op2}. This function produces correct
+results only when it is known in advance that @var{op2} divides
+@var{op1}.
+
+Since mpz_divexact is much faster than any of the other routines that produce
+the quotient (@pxref{References} Jebelean), it is the best choice for
+instances in which exact division is known to occur, such as reducing a
+rational to lowest terms.
+@end deftypefun
+
+@deftypefun void mpz_tdiv_q_2exp (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}. The quotient is
+rounded towards 0.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1}/2^{op2}$. The quotient is rounded towards 0.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_tdiv_r_2exp (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Divide @var{op1} by (2 raised to @var{op2}) and put the remainder in
+@var{rop}. Unless it is zero, @var{rop} will have the same sign as @var{op1}.
+@end ifinfo
+@iftex
+@tex
+Divide @var{op1} by $2^{op2}$ and put the remainder in @var{rop}. Unless it is
+zero, @var{rop} will have the same sign as @var{op1}.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_fdiv_q_2exp (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}. The quotient is
+rounded towards @minus{}infinity.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\lfloor@var{op1}/2^{op2}\rfloor$. The quotient is rounded
+towards $-\infty$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_fdiv_r_2exp (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Divide @var{op1} by (2 raised to @var{op2}) and put the remainder in
+@var{rop}. The sign of @var{rop} will always be positive.
+@end ifinfo
+@iftex
+@tex
+Divide @var{op1} by $2^{op2}$ and put the remainder in @var{rop}. The sign of
+@var{rop} will always be positive.
+@end tex
+@end iftex
+
+This operation can also be defined as masking of the @var{op2} least
+significant bits.
+@end deftypefun
+
+@subsection Exponentialization Functions
+
+@deftypefun void mpz_powm (mpz_t @var{rop}, mpz_t @var{base}, mpz_t @var{exp}, mpz_t @var{mod})
+@deftypefunx void mpz_powm_ui (mpz_t @var{rop}, mpz_t @var{base}, unsigned long int @var{exp}, mpz_t @var{mod})
+Set @var{rop} to (@var{base} raised to @var{exp}) @code{mod} @var{mod}. If
+@var{exp} is negative, the result is undefined.
+@end deftypefun
+
+@deftypefun void mpz_pow_ui (mpz_t @var{rop}, mpz_t @var{base}, unsigned long int @var{exp})
+@deftypefunx void mpz_ui_pow_ui (mpz_t @var{rop}, unsigned long int @var{base}, unsigned long int @var{exp})
+Set @var{rop} to @var{base} raised to @var{exp}.
+@ifinfo
+The case of 0^0 yields 1.
+@end ifinfo
+@iftex
+@tex
+The case of $0^0$ yields 1.
+@end tex
+@end iftex
+@end deftypefun
+
+@subsection Square Root Functions
+
+@deftypefun void mpz_sqrt (mpz_t @var{rop}, mpz_t @var{op})
+@ifinfo
+Set @var{rop} to the truncated integer part of the square root of
+@var{op}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\lfloor\sqrt{@var{op}}\rfloor$, the truncated integer
+part of the square root of @var{op}.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpz_sqrtrem (mpz_t @var{rop1}, mpz_t @var{rop2}, mpz_t @var{op})
+@ifinfo
+Set @var{rop1} to the truncated integer part of the square root of @var{op},
+like @code{mpz_sqrt}. Set @var{rop2} to
+@var{op}@minus{}@var{rop1}*@var{rop1},
+@end ifinfo
+@iftex
+@tex
+Set @var{rop1} to $\lfloor\sqrt{@var{op}}\rfloor$, like @code{mpz_sqrt}.
+Set @var{rop2} to $(@var{op} - @var{rop1}^2)$,
+@end tex
+@end iftex
+(i.e., zero if @var{op} is a perfect square).
+
+If @var{rop1} and @var{rop2} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun int mpz_perfect_square_p (mpz_t @var{op})
+Return non-zero if @var{op} is a perfect square, i.e., if the square root of
+@var{op} is an integer. Return zero otherwise.
+@end deftypefun
+
+@subsection Number Theoretic Functions
+
+@deftypefun int mpz_probab_prime_p (mpz_t @var{op}, int @var{reps})
+@ifinfo
+If this function returns 0, @var{op} is definitely not prime. If it returns
+1, then @var{op} is `probably' prime. The probability of a false positive is
+(1/4)**@var{reps}.
+@end ifinfo
+@iftex
+@tex
+If this function returns 0, @var{op} is definitely not prime. If it returns
+1, then @var{op} is `probably' prime. The probability of a false positive is
+$(1/4)^{{reps}}$.
+@end tex
+@end iftex
+A reasonable value of reps is 25.
+
+An implementation of the probabilistic primality test found in Seminumerical
+Algorithms (@pxref{References} Knuth).
+@end deftypefun
+
+@deftypefun void mpz_gcd (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+Set @var{rop} to the greatest common divisor of @var{op1} and @var{op2}.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_gcd_ui (mpz_t @var{rop}, mpz_t @var{op1}, unsigned long int @var{op2})
+Compute the greatest common divisor of @var{op1} and @var{op2}. If
+@var{rop} is not NULL, store the result there.
+
+If the result is small enough to fit in an @code{unsigned long int}, it is
+returned. If the result does not fit, 0 is returned, and the result is equal
+to the argument @var{op1}. Note that the result will always fit if @var{op2}
+is non-zero.
+@end deftypefun
+
+@deftypefun void mpz_gcdext (mpz_t @var{g}, mpz_t @var{s}, mpz_t @var{t}, mpz_t @var{a}, mpz_t @var{b})
+Compute @var{g}, @var{s}, and @var{t}, such that @var{a}@var{s} +
+@var{b}@var{t} = @var{g} = @code{gcd} (@var{a}, @var{b}). If @var{t} is
+NULL, that argument is not computed.
+@end deftypefun
+
+@deftypefun int mpz_invert (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+Compute the inverse of @var{op1} modulo @var{op2} and put the result in
+@var{rop}. Return non-zero if an inverse exist, zero otherwise. When the
+function returns zero, do not assume anything about the value in @var{rop}.
+@end deftypefun
+
+@deftypefun int mpz_jacobi (mpz_t @var{op1}, mpz_t @var{op2})
+@deftypefunx int mpz_legendre (mpz_t @var{op1}, mpz_t @var{op2})
+Compute the Jacobi and Legendre symbols, respectively.
+@end deftypefun
+
+@need 2000
+@node Comparison Functions, Integer Logic and Bit Fiddling, Integer Arithmetic, Integer Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+
+@deftypefun int mpz_cmp (mpz_t @var{op1}, mpz_t @var{op2})
+@ifinfo
+Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
+@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
+@var{op2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
+@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
+< @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefn Macro int mpz_cmp_ui (mpz_t @var{op1}, unsigned long int @var{op2})
+@deftypefnx Macro int mpz_cmp_si (mpz_t @var{op1}, signed long int @var{op2})
+@ifinfo
+Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
+@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
+@var{op2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
+@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
+< @var{op2}$.
+@end tex
+@end iftex
+
+These functions are actually implemented as macros. They evaluate their
+arguments multiple times.
+@end deftypefn
+
+@deftypefn Macro int mpz_sgn (mpz_t @var{op})
+@ifinfo
+Return +1 if @var{op} > 0, 0 if @var{op} = 0, and @minus{}1 if @var{op} < 0.
+@end ifinfo
+@iftex
+@tex
+Return $+1$ if $@var{op} > 0$, 0 if $@var{op} = 0$, and $-1$ if $@var{op} < 0$.
+@end tex
+@end iftex
+
+This function is actually implemented as a macro. It evaluates its
+arguments multiple times.
+@end deftypefn
+
+@node Integer Logic and Bit Fiddling, I/O of Integers, Comparison Functions, Integer Functions
+@comment node-name, next, previous, up
+@section Logical and Bit Manipulation Functions
+@cindex Logical functions
+@cindex Bit manipulation functions
+
+These functions behave as if two's complement arithmetic were used (although
+sign-magnitude is used by the actual implementation).
+
+@deftypefun void mpz_and (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+Set @var{rop} to @var{op1} logical-and @var{op2}.
+@end deftypefun
+
+@deftypefun void mpz_ior (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+Set @var{rop} to @var{op1} inclusive-or @var{op2}.
+@end deftypefun
+
+@c @deftypefun void mpz_xor (mpz_t @var{rop}, mpz_t @var{op1}, mpz_t @var{op2})
+@c Set @var{rop} to @var{op1} exclusive-or @var{op2}.
+@c @end deftypefun
+
+@deftypefun void mpz_com (mpz_t @var{rop}, mpz_t @var{op})
+Set @var{rop} to the one's complement of @var{op}.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_popcount (mpz_t @var{op})
+For non-negative numbers, return the population count of @var{op}. For
+negative numbers, return the largest possible value (@var{MAX_ULONG}).
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_hamdist (mpz_t @var{op1}, mpz_t @var{op2})
+If @var{op1} and @var{op2} are both non-negative, return the hamming distance
+between the two operands. Otherwise, return the largest possible value
+(@var{MAX_ULONG}).
+
+It is possible to extend this function to return a useful value when the
+operands are both negative, but the current implementation returns
+@var{MAX_ULONG} in this case. @strong{Do not depend on this behavior, since
+it will change in future versions of the library.}
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_scan0 (mpz_t @var{op}, unsigned long int @var{starting_bit})
+Scan @var{op}, starting with bit @var{starting_bit}, towards more significant
+bits, until the first clear bit is found. Return the index of the found bit.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpz_scan1 (mpz_t @var{op}, unsigned long int @var{starting_bit})
+Scan @var{op}, starting with bit @var{starting_bit}, towards more significant
+bits, until the first set bit is found. Return the index of the found bit.
+@end deftypefun
+
+@deftypefun void mpz_setbit (mpz_t @var{rop}, unsigned long int @var{bit_index})
+Set bit @var{bit_index} in @var{op1}.
+@end deftypefun
+
+@deftypefun void mpz_clrbit (mpz_t @var{rop}, unsigned long int @var{bit_index})
+Clear bit @var{bit_index} in @var{op1}.
+@end deftypefun
+
+@node I/O of Integers, Miscellaneous Integer Functions, Integer Logic and Bit Fiddling, Integer Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Integer input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream. Passing a NULL pointer for a @var{stream} argument to any of
+these functions will make them read from @code{stdin} and write to
+@code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{gmp.h}, since that will allow @file{gmp.h} to define prototypes
+for these functions.
+
+@deftypefun size_t mpz_out_str (FILE *@var{stream}, int @var{base}, mpz_t @var{op})
+Output @var{op} on stdio stream @var{stream}, as a string of digits in base
+@var{base}. The base may vary from 2 to 36.
+
+Return the number of bytes written, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpz_inp_str (mpz_t @var{rop}, FILE *@var{stream}, int @var{base})
+Input a possibly white-space preceded string in base @var{base} from stdio
+stream @var{stream}, and put the read integer in @var{rop}. The base may vary
+from 2 to 36. If @var{base} is 0, the actual base is determined from the
+leading characters: if the first two characters are `0x' or `0X', hexadecimal
+is assumed, otherwise if the first character is `0', octal is assumed,
+otherwise decimal is assumed.
+
+Return the number of bytes read, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpz_out_raw (FILE *@var{stream}, mpz_t @var{op})
+Output @var{op} on stdio stream @var{stream}, in raw binary format. The
+integer is written in a portable format, with 4 bytes of size information, and
+that many bytes of limbs. Both the size and the limbs are written in
+decreasing significance order (i.e., in big-endian).
+
+The output can be read with @code{mpz_inp_raw}.
+
+Return the number of bytes written, or if an error occurred, return 0.
+
+The output of this can not be read by @code{mpz_inp_raw} from GMP 1, because
+of changes necessary for compatibility between 32-bit and 64-bit machines.
+@end deftypefun
+
+@deftypefun size_t mpz_inp_raw (mpz_t @var{rop}, FILE *@var{stream})
+Input from stdio stream @var{stream} in the format written by
+@code{mpz_out_raw}, and put the result in @var{rop}. Return the number of
+bytes read, or if an error occurred, return 0.
+
+This routine can read the output from @code{mpz_out_raw} also from GMP 1, in
+spite of changes necessary for compatibility between 32-bit and 64-bit
+machines.
+@end deftypefun
+
+
+@need 2000
+@node Miscellaneous Integer Functions,, I/O of Integers, Integer Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+@cindex Miscellaneous integer functions
+
+@deftypefun void mpz_random (mpz_t @var{rop}, mp_size_t @var{max_size})
+Generate a random integer of at most @var{max_size} limbs. The generated
+random number doesn't satisfy any particular requirements of randomness.
+Negative random numbers are generated when @var{max_size} is negative.
+@end deftypefun
+
+@deftypefun void mpz_random2 (mpz_t @var{rop}, mp_size_t @var{max_size})
+Generate a random integer of at most @var{max_size} limbs, with long strings
+of zeros and ones in the binary representation. Useful for testing functions
+and algorithms, since this kind of random numbers have proven to be more
+likely to trigger corner-case bugs. Negative random numbers are generated
+when @var{max_size} is negative.
+@end deftypefun
+
+@deftypefun size_t mpz_size (mpz_t @var{op})
+Return the size of @var{op} measured in number of limbs. If @var{op} is zero,
+the returned value will be zero.
+@c (@xref{Nomenclature}, for an explanation of the concept @dfn{limb}.)
+
+@strong{This function is obsolete. It will disappear from future MP
+releases.}
+@end deftypefun
+
+@deftypefun size_t mpz_sizeinbase (mpz_t @var{op}, int @var{base})
+Return the size of @var{op} measured in number of digits in base @var{base}.
+The base may vary from 2 to 36. The returned value will be exact or 1 too
+big. If @var{base} is a power of 2, the returned value will always be exact.
+
+This function is useful in order to allocate the right amount of space before
+converting @var{op} to a string. The right amount of allocation is normally
+two more than the value returned by @code{mpz_sizeinbase} (one extra for a
+minus sign and one for the terminating '\0').
+@end deftypefun
+
+
+@node Rational Number Functions, Floating-point Functions, Integer Functions, Top
+@comment node-name, next, previous, up
+@chapter Rational Number Functions
+@cindex Rational number functions
+
+This chapter describes the MP functions for performing arithmetic on rational
+numbers. These functions start with the prefix @code{mpq_}.
+
+Rational numbers are stored in objects of type @code{mpq_t}.
+
+All rational arithmetic functions assume operands have a canonical form, and
+canonicalize their result. The canonical from means that the denominator and
+the numerator have no common factors, and that the denominator is positive.
+Zero has the unique representation 0/1.
+
+Pure assignment functions do not canonicalize the assigned variable. It is
+the responsibility of the user to canonicalize the assigned variable before
+any arithmetic operations are performed on that variable. @strong{Note that
+this is an incompatible change from version 1 of the library.}
+
+@deftypefun void mpq_canonicalize (mpq_t @var{op})
+Remove any factors that are common to the numerator and denominator of
+@var{op}, and make the denominator positive.
+@end deftypefun
+
+@menu
+* Initializing Rationals::
+* Assigning Rationals::
+* Simultaneous Integer Init & Assign::
+* Comparing Rationals::
+* Applying Integer Functions::
+* Miscellaneous Rational Functions::
+@end menu
+
+@node Initializing Rationals, Assigning Rationals, Rational Number Functions, Rational Number Functions
+@comment node-name, next, previous, up
+@section Initialization and Assignment Functions
+
+@deftypefun void mpq_init (mpq_t @var{dest_rational})
+Initialize @var{dest_rational} and set it to 0/1. Each variable should
+normally only be initialized once, or at least cleared out (using the function
+@code{mpq_clear}) between each initialization.
+@end deftypefun
+
+@deftypefun void mpq_clear (mpq_t @var{rational_number})
+Free the space occupied by @var{rational_number}. Make sure to call this
+function for all @code{mpq_t} variables when you are done with them.
+@end deftypefun
+
+@deftypefun void mpq_set (mpq_t @var{rop}, mpq_t @var{op})
+@deftypefunx void mpq_set_z (mpq_t @var{rop}, mpz_t @var{op})
+Assign @var{rop} from @var{op}.
+@end deftypefun
+
+@deftypefun void mpq_set_ui (mpq_t @var{rop}, unsigned long int @var{op1}, unsigned long int @var{op2})
+@deftypefunx void mpq_set_si (mpq_t @var{rop}, signed long int @var{op1}, unsigned long int @var{op2})
+Set the value of @var{rop} to @var{op1}/@var{op2}. Note that if @var{op1} and
+@var{op2} have common factors, @var{rop} has to be passed to
+@code{mpq_canonicalize} before any operations are performed on @var{rop}.
+@end deftypefun
+
+@node Assigning Rationals, Comparing Rationals, Initializing Rationals, Rational Number Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+
+@deftypefun void mpq_add (mpq_t @var{sum}, mpq_t @var{addend1}, mpq_t @var{addend2})
+Set @var{sum} to @var{addend1} + @var{addend2}.
+@end deftypefun
+
+@deftypefun void mpq_sub (mpq_t @var{difference}, mpq_t @var{minuend}, mpq_t @var{subtrahend})
+Set @var{difference} to @var{minuend} @minus{} @var{subtrahend}.
+@end deftypefun
+
+@deftypefun void mpq_mul (mpq_t @var{product}, mpq_t @var{multiplier}, mpq_t @var{multiplicand})
+@ifinfo
+Set @var{product} to @var{multiplier} times @var{multiplicand}.
+@end ifinfo
+@iftex
+@tex
+Set @var{product} to $@var{multiplier} \times @var{multiplicand}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpq_div (mpq_t @var{quotient}, mpq_t @var{dividend}, mpq_t @var{divisor})
+Set @var{quotient} to @var{dividend}/@var{divisor}.
+@end deftypefun
+
+@deftypefun void mpq_neg (mpq_t @var{negated_operand}, mpq_t @var{operand})
+Set @var{negated_operand} to @minus{}@var{operand}.
+@end deftypefun
+
+@deftypefun void mpq_inv (mpq_t @var{inverted_number}, mpq_t @var{number})
+Set @var{inverted_number} to 1/@var{number}. If the new denominator is
+zero, this routine will divide by zero.
+@end deftypefun
+
+@node Comparing Rationals, Applying Integer Functions, Assigning Rationals, Rational Number Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+
+@deftypefun int mpq_cmp (mpq_t @var{op1}, mpq_t @var{op2})
+@ifinfo
+Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
+@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
+@var{op2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
+@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
+< @var{op2}$.
+@end tex
+@end iftex
+
+To determine if two rationals are equal, @code{mpq_equal} is faster than
+@code{mpq_cmp}.
+@end deftypefun
+
+@deftypefn Macro int mpq_cmp_ui (mpq_t @var{op1}, unsigned long int @var{num2}, unsigned long int @var{den2})
+@ifinfo
+Compare @var{op1} and @var{num2}/@var{den2}. Return a positive value if
+@var{op1} > @var{num2}/@var{den2}, zero if @var{op1} = @var{num2}/@var{den2},
+and a negative value if @var{op1} < @var{num2}/@var{den2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{num2}/@var{den2}. Return a positive value if
+$@var{op1} > @var{num2}/@var{den2}$, zero if $@var{op1} =
+@var{num2}/@var{den2}$, and a negative value if $@var{op1} <
+@var{num2}/@var{den2}$.
+@end tex
+@end iftex
+
+This routine allows that @var{num2} and @var{den2} have common factors.
+
+This function is actually implemented as a macro. It evaluates its
+arguments multiple times.
+@end deftypefn
+
+@deftypefn Macro int mpq_sgn (mpq_t @var{op})
+@ifinfo
+Return +1 if @var{op} > 0, 0 if @var{op} = 0, and @minus{}1 if @var{op} < 0.
+@end ifinfo
+@iftex
+@tex
+Return $+1$ if $@var{op} > 0$, 0 if $@var{op} = 0$, and $-1$ if $@var{op} < 0$.
+@end tex
+@end iftex
+
+This function is actually implemented as a macro. It evaluates its
+arguments multiple times.
+@end deftypefn
+
+@deftypefun int mpq_equal (mpq_t @var{op1}, mpq_t @var{op2})
+Return non-zero if @var{op1} and @var{op2} are equal, zero if they are
+non-equal. Although @code{mpq_cmp} can be used for the same purpose, this
+function is much faster.
+@end deftypefun
+
+@node Applying Integer Functions, Miscellaneous Rational Functions, Comparing Rationals, Rational Number Functions
+@comment node-name, next, previous, up
+@section Applying Integer Functions to Rationals
+
+The set of @code{mpq} functions is quite small. In particular, there are no
+functions for either input or output. But there are two macros that allow us
+to apply any @code{mpz} function on the numerator or denominator of a rational
+number. If these macros are used to assign to the rational number,
+@code{mpq_canonicalize} normally need to be called afterwards.
+
+@deftypefn Macro mpz_t mpq_numref (mpq_t @var{op})
+@deftypefnx Macro mpz_t mpq_denref (mpq_t @var{op})
+Return a reference to the numerator and denominator of @var{op}, respectively.
+The @code{mpz} functions can be used on the result of these macros.
+@end deftypefn
+
+@need 2000
+@node Miscellaneous Rational Functions, , Applying Integer Functions, Rational Number Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+
+@deftypefun double mpq_get_d (mpq_t @var{op})
+Convert @var{op} to a double.
+@end deftypefun
+
+These functions assign between either the numerator or denominator of a
+rational, and an integer. Instead of using these functions, it is preferable
+to use the more general mechanisms @code{mpq_numref} and @code{mpq_denref},
+together with @code{mpz_set}.
+
+@deftypefun void mpq_set_num (mpq_t @var{rational}, mpz_t @var{numerator})
+Copy @var{numerator} to the numerator of @var{rational}. When this risks to
+make the numerator and denominator of @var{rational} have common factors, you
+have to pass @var{rational} to @code{mpq_canonicalize} before any operations
+are performed on @var{rational}.
+
+This function is equivalent to
+@code{mpz_set (mpq_numref (@var{rational}), @var{numerator})}.
+@end deftypefun
+
+@deftypefun void mpq_set_den (mpq_t @var{rational}, mpz_t @var{denominator})
+Copy @var{denominator} to the denominator of @var{rational}. When this risks
+to make the numerator and denominator of @var{rational} have common factors,
+or if the denominator might be negative, you have to pass @var{rational} to
+@code{mpq_canonicalize} before any operations are performed on @var{rational}.
+
+@strong{In version 1 of the library, negative denominators were handled by
+copying the sign to the numerator. That is no longer done.}
+
+This function is equivalent to
+@code{mpz_set (mpq_denref (@var{rational}), @var{denominators})}.
+@end deftypefun
+
+@deftypefun void mpq_get_num (mpz_t @var{numerator}, mpq_t @var{rational})
+Copy the numerator of @var{rational} to the integer @var{numerator}, to
+prepare for integer operations on the numerator.
+
+This function is equivalent to
+@code{mpz_set (@var{numerator}, mpq_numref (@var{rational}))}.
+@end deftypefun
+
+@deftypefun void mpq_get_den (mpz_t @var{denominator}, mpq_t @var{rational})
+Copy the denominator of @var{rational} to the integer @var{denominator}, to
+prepare for integer operations on the denominator.
+
+This function is equivalent to
+@code{mpz_set (@var{denominator}, mpq_denref (@var{rational}))}.
+@end deftypefun
+
+
+@node Floating-point Functions, Low-level Functions, Rational Number Functions, Top
+@comment node-name, next, previous, up
+@chapter Floating-point Functions
+@cindex Floating-point functions
+@cindex Float functions
+
+This is a description of the @emph{preliminary} interface for floating-point
+arithmetic in GNU MP 2.
+
+The floating-point functions expect arguments of type @code{mpf_t}.
+
+The MP floating-point functions have an interface that is similar to the MP
+integer functions. The function prefix for floating-point operations is
+@code{mpf_}.
+
+There is one significant characteristic of floating-point numbers that has
+motivated a difference between this function class and other MP function
+classes: the inherent inexactness of floating point arithmetic. The user has
+to specify the precision of each variable. A computation that assigns a
+variable will take place with the precision of the assigned variable; the
+precision of variables used as input is ignored.
+
+@cindex User-defined precision
+The precision of a calculation is defined as follows: Compute the requested
+operation exactly (with ``infinite precision''), and truncate the result to
+the destination variable precision. Even if the user has asked for a very
+high precision, MP will not calculate with superfluous digits. For example,
+if two low-precision numbers of nearly equal magnitude are added, the
+precision of the result will be limited to what is required to represent the
+result accurately.
+
+The MP floating-point functions are @emph{not} intended as a smooth extension
+to the IEEE P754 arithmetic. Specifically, the results obtained on one
+computer often differs from the results obtained on a computer with a
+different word size.
+
+@menu
+* Initializing Floats::
+* Assigning Floats::
+* Simultaneous Float Init & Assign::
+* Converting Floats::
+* Float Arithmetic::
+* Float Comparison::
+* I/O of Floats::
+* Miscellaneous Float Functions::
+@end menu
+
+@node Initializing Floats, Assigning Floats, , Floating-point Functions
+@comment node-name, next, previous, up
+@section Initialization and Assignment Functions
+
+@deftypefun void mpf_set_default_prec (unsigned long int @var{prec})
+Set the default precision to be @strong{at least} @var{prec} bits. All
+subsequent calls to @code{mpf_init} will use this precision, but previously
+initialized variables are unaffected.
+@end deftypefun
+
+An @code{mpf_t} object must be initialized before storing the first value in
+it. The functions @code{mpf_init} and @code{mpf_init2} are used for that
+purpose.
+
+@deftypefun void mpf_init (mpf_t @var{x})
+Initialize @var{x} to 0. Normally, a variable should be initialized once only
+or at least be cleared, using @code{mpf_clear}, between initializations. The
+precision of @var{x} is undefined unless a default precision has already been
+established by a call to @code{mpf_set_default_prec}.
+@end deftypefun
+
+@deftypefun void mpf_init2 (mpf_t @var{x}, unsigned long int @var{prec})
+Initialize @var{x} to 0 and set its precision to be @strong{at least}
+@var{prec} bits. Normally, a variable should be initialized once only or at
+least be cleared, using @code{mpf_clear}, between initializations.
+@end deftypefun
+
+@deftypefun void mpf_clear (mpf_t @var{x})
+Free the space occupied by @var{x}. Make sure to call this function for all
+@code{mpf_t} variables when you are done with them.
+@end deftypefun
+
+@need 2000
+Here is an example on how to initialize floating-point variables:
+@example
+@{
+ mpf_t x, y;
+ mpf_init (x); /* use default precision */
+ mpf_init2 (y, 256); /* precision @emph{at least} 256 bits */
+ @dots{}
+ /* Unless the program is about to exit, do ... */
+ mpf_clear (x);
+ mpf_clear (y);
+@}
+@end example
+
+The following three functions are useful for changing the precision during a
+calculation. A typical use would be for adjusting the precision gradually in
+iterative algorithms like Newton-Raphson, making the computation precision
+closely match the actual accurate part of the numbers.
+
+@deftypefun void mpf_set_prec (mpf_t @var{rop}, unsigned long int @var{prec})
+Set the precision of @var{rop} to be @strong{at least} @var{prec} bits.
+Since changing the precision involves calls to @code{realloc}, this routine
+should not be called in a tight loop.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpf_get_prec (mpf_t @var{op})
+Return the precision actually used for assignments of @var{op}.
+@end deftypefun
+
+@deftypefun void mpf_set_prec_raw (mpf_t @var{rop}, unsigned long int @var{prec})
+Set the precision of @var{rop} to be @strong{at least} @var{prec} bits. This
+is a low-level function that does not change the allocation. The @var{prec}
+argument must not be larger that the precision previously returned by
+@code{mpf_get_prec}. It is crucial that the precision of @var{rop} is
+ultimately reset to exactly the value returned by @code{mpf_get_prec}.
+@end deftypefun
+
+
+@node Assigning Floats, Simultaneous Float Init & Assign, Initializing Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@subsection Assignment Functions
+@cindex Float assignment functions
+
+These functions assign new values to already initialized floats
+(@pxref{Initializing Floats}).
+
+@deftypefun void mpf_set (mpf_t @var{rop}, mpf_t @var{op})
+@deftypefunx void mpf_set_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpf_set_si (mpf_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpf_set_d (mpf_t @var{rop}, double @var{op})
+@deftypefunx void mpf_set_z (mpf_t @var{rop}, mpz_t @var{op})
+@deftypefunx void mpf_set_q (mpf_t @var{rop}, mpq_t @var{op})
+Set the value of @var{rop} from @var{op}.
+@end deftypefun
+
+@deftypefun int mpf_set_str (mpf_t @var{rop}, char *@var{str}, int @var{base})
+Set the value of @var{rop} from the string in @var{str}. The string is of the
+form @samp{M@@N} or, if the base is 10 or less, alternatively @samp{MeN}.
+@samp{M} is the mantissa and @samp{N} is the exponent. The mantissa is always
+in the specified base. The exponent is either in the specified base or, if
+@var{base} is negative, in decimal.
+
+The argument @var{base} may be in the ranges 2 to 36, or @minus{}36 to
+@minus{}2. Negative values are used to specify that the exponent is in
+decimal.
+
+Unlike the corresponding @code{mpz} function, the base will not be determined
+from the leading characters of the string if @var{base} is 0. This is so that
+numbers like @samp{0.23} are not interpreted as octal.
+
+White space is allowed in the string, and is simply ignored.
+
+This function returns 0 if the entire string up to the '\0' is a valid number
+in base @var{base}. Otherwise it returns @minus{}1.
+@end deftypefun
+
+
+@node Simultaneous Float Init & Assign, Converting Floats, Assigning Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@subsection Combined Initialization and Assignment Functions
+@cindex Initialization and assignment functions
+
+For convenience, MP provides a parallel series of initialize-and-set functions
+which initialize the output and then store the value there. These functions'
+names have the form @code{mpf_init_set@dots{}}
+
+Once the float has been initialized by any of the @code{mpf_init_set@dots{}}
+functions, it can be used as the source or destination operand for the ordinary
+float functions. Don't use an initialize-and-set function on a variable
+already initialized!
+
+@deftypefun void mpf_init_set (mpf_t @var{rop}, mpf_t @var{op})
+@deftypefunx void mpf_init_set_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@deftypefunx void mpf_init_set_si (mpf_t @var{rop}, signed long int @var{op})
+@deftypefunx void mpf_init_set_d (mpf_t @var{rop}, double @var{op})
+Initialize @var{rop} and set its value from @var{op}.
+
+The precision of @var{rop} will be taken from the active default precision, as
+set by @code{mpf_set_default_prec}.
+@end deftypefun
+
+@deftypefun int mpf_init_set_str (mpf_t @var{rop}, char *@var{str}, int @var{base})
+Initialize @var{rop} and set its value from the string in @var{str}. See
+@code{mpf_set_str} above for details on the assignment operation.
+
+Note that @var{rop} is initialized even if an error occurs. (I.e., you have to
+call @code{mpf_clear} for it.)
+
+The precision of @var{rop} will be taken from the active default precision, as
+set by @code{mpf_set_default_prec}.
+@end deftypefun
+
+
+@node Converting Floats, Float Arithmetic, Simultaneous Float Init & Assign, Floating-point Functions
+@comment node-name, next, previous, up
+@section Conversion Functions
+@cindex Conversion functions
+
+@deftypefun double mpf_get_d (mpf_t @var{op})
+Convert @var{op} to a double.
+@end deftypefun
+
+@deftypefun {char *} mpf_get_str (char *@var{str}, mp_exp_t *@var{expptr}, int @var{base}, size_t @var{n_digits}, mpf_t @var{op})
+Convert @var{op} to a string of digits in base @var{base}. The base may vary
+from 2 to 36. Generate at most @var{n_digits} significant digits, or if
+@var{n_digits} is 0, the maximum number of digits accurately representable by
+@var{op}.
+
+If @var{str} is NULL, space for the mantissa is allocated using the default
+allocation function, and a pointer to the string is returned.
+
+If @var{str} is not NULL, it should point to a block of storage enough large
+for the mantissa, i.e., @var{n_digits} + 2. The two extra bytes are for a
+possible minus sign, and for the terminating null character.
+
+The exponent is written through the pointer @var{expptr}.
+
+If @var{n_digits} is 0, the maximum number of digits meaningfully achievable
+from the precision of @var{op} will be generated. Note that the space
+requirements for @var{str} in this case will be impossible for the user to
+predetermine. Therefore, you need to pass NULL for the string argument
+whenever @var{n_digits} is 0.
+
+The generated string is a fraction, with an implicit radix point immediately
+to the left of the first digit. For example, the number 3.1416 would be
+returned as "31416" in the string and 1 written at @var{expptr}.
+@end deftypefun
+
+
+@node Float Arithmetic, Float Comparison, Converting Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Arithmetic Functions
+@cindex Float arithmetic functions
+@cindex Arithmetic functions
+
+@deftypefun void mpf_add (mpf_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_add_ui (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} + @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} + @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpf_sub (mpf_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_ui_sub (mpf_t @var{rop}, unsigned long int @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_sub_ui (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @var{op1} @minus{} @var{op2}.
+@end deftypefun
+
+@deftypefun void mpf_mul (mpf_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_mul_ui (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} times @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+Division is undefined if the divisor is zero, and passing a zero divisor to
+the divide functions will make these functions intentionally divide by zero.
+This gives the user the possibility to handle arithmetic exceptions in these
+functions in the same manner as other arithmetic exceptions.
+
+@deftypefun void mpf_div (mpf_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_ui_div (mpf_t @var{rop}, unsigned long int @var{op1}, mpf_t @var{op2})
+@deftypefunx void mpf_div_ui (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+Set @var{rop} to @var{op1}/@var{op2}.
+@end deftypefun
+
+@deftypefun void mpf_sqrt (mpf_t @var{rop}, mpf_t @var{op})
+@deftypefunx void mpf_sqrt_ui (mpf_t @var{rop}, unsigned long int @var{op})
+@ifinfo
+Set @var{rop} to the square root of @var{op}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $\sqrt{@var{op}}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@c @deftypefun void mpf_pow_ui (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+@c Set @var{rop} to @var{op1} raised to @var{op2}.
+@c @end deftypefun
+
+@deftypefun void mpf_neg (mpf_t @var{rop}, mpf_t @var{op})
+Set @var{rop} to @minus{}@var{op}.
+@end deftypefun
+
+@deftypefun void mpf_abs (mpf_t @var{rop}, mpf_t @var{op})
+Set @var{rop} to the absolute value of @var{op}.
+@end deftypefun
+
+@deftypefun void mpf_mul_2exp (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} times 2 raised to @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1} \times 2^{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun void mpf_div_2exp (mpf_t @var{rop}, mpf_t @var{op1}, unsigned long int @var{op2})
+@ifinfo
+Set @var{rop} to @var{op1} divided by 2 raised to @var{op2}.
+@end ifinfo
+@iftex
+@tex
+Set @var{rop} to $@var{op1}/2^{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@node Float Comparison, I/O of Floats, Float Arithmetic, Floating-point Functions
+@comment node-name, next, previous, up
+@section Comparison Functions
+@cindex Float comparisons functions
+@cindex Comparison functions
+
+@deftypefun int mpf_cmp (mpf_t @var{op1}, mpf_t @var{op2})
+@deftypefunx int mpf_cmp_ui (mpf_t @var{op1}, unsigned long int @var{op2})
+@deftypefunx int mpf_cmp_si (mpf_t @var{op1}, signed long int @var{op2})
+@ifinfo
+Compare @var{op1} and @var{op2}. Return a positive value if @var{op1} >
+@var{op2}, zero if @var{op1} = @var{op2}, and a negative value if @var{op1} <
+@var{op2}.
+@end ifinfo
+@iftex
+@tex
+Compare @var{op1} and @var{op2}. Return a positive value if $@var{op1} >
+@var{op2}$, zero if $@var{op1} = @var{op2}$, and a negative value if $@var{op1}
+< @var{op2}$.
+@end tex
+@end iftex
+@end deftypefun
+
+@deftypefun int mpf_eq (mpf_t @var{op1}, mpf_t @var{op2}, unsigned long int op3)
+Return non-zero if the first @var{op3} bits of @var{op1} and @var{op2} are
+equal, zero otherwise. I.e., test of @var{op1} and @var{op2} are
+approximately equal.
+@end deftypefun
+
+@deftypefun void mpf_reldiff (mpf_t @var{rop}, mpf_t @var{op1}, mpf_t @var{op2})
+Compute the relative difference between @var{op1} and @var{op2} and store the
+result in @var{rop}.
+@end deftypefun
+
+@deftypefn Macro int mpf_sgn (mpf_t @var{op})
+@ifinfo
+Return +1 if @var{op} > 0, 0 if @var{op} = 0, and @minus{}1 if @var{op} < 0.
+@end ifinfo
+@iftex
+@tex
+Return $+1$ if $@var{op} > 0$, 0 if $@var{op} = 0$, and $-1$ if $@var{op} < 0$.
+@end tex
+@end iftex
+
+This function is actually implemented as a macro. It evaluates its
+arguments multiple times.
+@end deftypefn
+
+@node I/O of Floats, Miscellaneous Float Functions, Float Comparison, Floating-point Functions
+@comment node-name, next, previous, up
+@section Input and Output Functions
+@cindex Float input and output functions
+@cindex Input functions
+@cindex Output functions
+@cindex I/O functions
+
+Functions that perform input from a stdio stream, and functions that output to
+a stdio stream. Passing a NULL pointer for a @var{stream} argument to any of
+these functions will make them read from @code{stdin} and write to
+@code{stdout}, respectively.
+
+When using any of these functions, it is a good idea to include @file{stdio.h}
+before @file{gmp.h}, since that will allow @file{gmp.h} to define prototypes
+for these functions.
+
+@deftypefun size_t mpf_out_str (FILE *@var{stream}, int @var{base}, size_t @var{n_digits}, mpf_t @var{op})
+Output @var{op} on stdio stream @var{stream}, as a string of digits in
+base @var{base}. The base may vary from 2 to 36. Print at most
+@var{n_digits} significant digits, or if @var{n_digits} is 0, the maximum
+number of digits accurately representable by @var{op}.
+
+In addition to the significant digits, a leading @samp{0.} and a
+trailing exponent, in the form @samp{eNNN}, are printed. If @var{base}
+is greater than 10, @samp{@@} will be used instead of @samp{e} as
+exponent delimiter.
+
+Return the number of bytes written, or if an error occurred, return 0.
+@end deftypefun
+
+@deftypefun size_t mpf_inp_str (mpf_t @var{rop}, FILE *@var{stream}, int @var{base})
+Input a string in base @var{base} from stdio stream @var{stream}, and put the
+read float in @var{rop}. The string is of the form @samp{M@@N} or, if the
+base is 10 or less, alternatively @samp{MeN}. @samp{M} is the mantissa and
+@samp{N} is the exponent. The mantissa is always in the specified base. The
+exponent is either in the specified base or, if @var{base} is negative, in
+decimal.
+
+The argument @var{base} may be in the ranges 2 to 36, or @minus{}36 to
+@minus{}2. Negative values are used to specify that the exponent is in
+decimal.
+
+Unlike the corresponding @code{mpz} function, the base will not be determined
+from the leading characters of the string if @var{base} is 0. This is so that
+numbers like @samp{0.23} are not interpreted as octal.
+
+Return the number of bytes read, or if an error occurred, return 0.
+@end deftypefun
+
+@c @deftypefun void mpf_out_raw (FILE *@var{stream}, mpf_t @var{float})
+@c Output @var{float} on stdio stream @var{stream}, in raw binary
+@c format. The float is written in a portable format, with 4 bytes of
+@c size information, and that many bytes of limbs. Both the size and the
+@c limbs are written in decreasing significance order.
+@c @end deftypefun
+
+@c @deftypefun void mpf_inp_raw (mpf_t @var{float}, FILE *@var{stream})
+@c Input from stdio stream @var{stream} in the format written by
+@c @code{mpf_out_raw}, and put the result in @var{float}.
+@c @end deftypefun
+
+
+@node Miscellaneous Float Functions, , I/O of Floats, Floating-point Functions
+@comment node-name, next, previous, up
+@section Miscellaneous Functions
+@cindex Miscellaneous float functions
+
+@deftypefun void mpf_random2 (mpf_t @var{rop}, mp_size_t @var{max_size}, mp_exp_t @var{max_exp})
+Generate a random float of at most @var{max_size} limbs, with long strings of
+zeros and ones in the binary representation. The exponent of the number is in
+the interval @minus{}@var{exp} to @var{exp}. This function is useful for
+testing functions and algorithms, since this kind of random numbers have
+proven to be more likely to trigger corner-case bugs. Negative random numbers
+are generated when @var{max_size} is negative.
+@end deftypefun
+
+@c @deftypefun size_t mpf_size (mpf_t @var{op})
+@c Return the size of @var{op} measured in number of limbs. If @var{op} is
+@c zero, the returned value will be zero. (@xref{Nomenclature}, for an
+@c explanation of the concept @dfn{limb}.)
+@c
+@c @strong{This function is obsolete. It will disappear from future MP
+@c releases.}
+@c @end deftypefun
+
+@node Low-level Functions, BSD Compatible Functions, Floating-point Functions, Top
+@comment node-name, next, previous, up
+@chapter Low-level Functions
+@cindex Low-level functions
+
+This chapter describes low-level MP functions, used to implement the high-level
+MP functions, but also intended for time-critical user code.
+
+These functions start with the prefix @code{mpn_}.
+
+@c 1. Some of these function clobber input operands.
+@c
+
+The @code{mpn} functions are designed to be as fast as possible, @strong{not}
+to provide a coherent calling interface. The different functions have somewhat
+similar interfaces, but there are variations that make them hard to use. These
+functions do as little as possible apart from the real multiple precision
+computation, so that no time is spent on things that not all callers need.
+
+A source operand is specified by a pointer to the least significant limb and a
+limb count. A destination operand is specified by just a pointer. It is the
+responsibility of the caller to ensure that the destination has enough space
+for storing the result.
+
+With this way of specifying operands, it is possible to perform computations
+on subranges of an argument, and store the result into a subrange of a
+destination.
+
+A common requirement for all functions is that each source area needs at least
+one limb. No size argument may be zero.
+
+The @code{mpn} functions is the base for the implementation of the @code{mpz_},
+@code{mpf_}, and @code{mpq_} functions.
+
+This example adds the number beginning at @var{src1_ptr} and the number
+beginning at @var{src2_ptr} and writes the sum at @var{dest_ptr}. All areas
+have @var{size} limbs.
+
+@example
+cy = mpn_add_n (dest_ptr, src1_ptr, src2_ptr, size)
+@end example
+
+@noindent
+In the notation used here, a source operand is identified by the pointer to
+the least significant limb, and the limb count in braces. For example,
+@{s1_ptr, s1_size@}.
+
+@deftypefun mp_limb_t mpn_add_n (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{size})
+Add @{@var{src1_ptr}, @var{size}@} and @{@var{src2_ptr}, @var{size}@}, and
+write the @var{size} least significant limbs of the result to @var{dest_ptr}.
+Return carry, either 0 or 1.
+
+This is the lowest-level function for addition. It is the preferred function
+for addition, since it is written in assembly for most targets. For addition
+of a variable to itself (i.e., @var{src1_ptr} equals @var{src2_ptr}, use
+@code{mpn_lshift} with a count of 1 for optimal speed.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_add_1 (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{size}, mp_limb_t @var{src2_limb})
+Add @{@var{src1_ptr}, @var{size}@} and @var{src2_limb}, and write the
+@var{size} least significant limbs of the result to @var{dest_ptr}. Return
+carry, either 0 or 1.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_add (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{src1_size}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{src2_size})
+Add @{@var{src1_ptr}, @var{src1_size}@} and @{@var{src2_ptr},
+@var{src2_size}@}, and write the @var{src1_size} least significant limbs of
+the result to @var{dest_ptr}. Return carry, either 0 or 1.
+
+This function requires that @var{src1_size} is greater than or equal to
+@var{src2_size}.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub_n (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{size})
+Subtract @{@var{src2_ptr}, @var{src2_size}@} from @{@var{src1_ptr},
+@var{size}@}, and write the @var{size} least significant limbs of the result
+to @var{dest_ptr}. Return borrow, either 0 or 1.
+
+This is the lowest-level function for subtraction. It is the preferred
+function for subtraction, since it is written in assembly for most targets.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub_1 (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{size}, mp_limb_t @var{src2_limb})
+Subtract @var{src2_limb} from @{@var{src1_ptr}, @var{size}@}, and write the
+@var{size} least significant limbs of the result to @var{dest_ptr}. Return
+borrow, either 0 or 1.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_sub (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{src1_size}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{src2_size})
+Subtract @{@var{src2_ptr}, @var{src2_size}@} from @{@var{src1_ptr},
+@var{src1_size}@}, and write the @var{src1_size} least significant limbs of
+the result to @var{dest_ptr}. Return borrow, either 0 or 1.
+
+This function requires that @var{src1_size} is greater than or equal to
+@var{src2_size}.
+@end deftypefun
+
+@deftypefun void mpn_mul_n (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{size})
+Multiply @{@var{src1_ptr}, @var{size}@} and @{@var{src2_ptr}, @var{size}@},
+and write the @strong{entire} result to @var{dest_ptr}.
+
+The destination has to have space for 2@var{size} limbs, even if the
+significant result might be one limb smaller.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_mul_1 (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{size}, mp_limb_t @var{src2_limb})
+Multiply @{@var{src1_ptr}, @var{size}@} and @var{src2_limb}, and write the
+@var{size} least significant limbs of the product to @var{dest_ptr}. Return
+the most significant limb of the product.
+
+This is a low-level function that is a building block for general
+multiplication as well as other operations in MP. It is written in assembly
+for most targets.
+
+Don't call this function if @var{src2_limb} is a power of 2; use
+@code{mpn_lshift} with a count equal to the logarithm of @var{src2_limb}
+instead, for optimal speed.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_addmul_1 (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{size}, mp_limb_t @var{src2_limb})
+Multiply @{@var{src1_ptr}, @var{size}@} and @var{src2_limb}, and add the
+@var{size} least significant limbs of the product to @{@var{dest_ptr},
+@var{size}@} and write the result to @var{dest_ptr} @var{dest_ptr}. Return
+the most significant limb of the product, plus carry-out from the addition.
+
+This is a low-level function that is a building block for general
+multiplication as well as other operations in MP. It is written in assembly
+for most targets.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_submul_1 (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{size}, mp_limb_t @var{src2_limb})
+Multiply @{@var{src1_ptr}, @var{size}@} and @var{src2_limb}, and subtract the
+@var{size} least significant limbs of the product from @{@var{dest_ptr},
+@var{size}@} and write the result to @var{dest_ptr}. Return the most
+significant limb of the product, minus borrow-out from the subtraction.
+
+This is a low-level function that is a building block for general
+multiplication and division as well as other operations in MP. It is written
+in assembly for most targets.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_mul (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src1_ptr}, mp_size_t @var{src1_size}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{src2_size})
+Multiply @{@var{src1_ptr}, @var{src1_size}@} and @{@var{src2_ptr},
+@var{src2_size}@}, and write the result to @var{dest_ptr}. Return the most
+significant limb of the result.
+
+The destination has to have space for @var{src1_size} + @var{src1_size}
+limbs, even if the result might be one limb smaller.
+
+This function requires that @var{src1_size} is greater than or equal to
+@var{src2_size}. The destination must be distinct from either input operands.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_divrem (mp_limb_t * @var{r1p}, mp_size_t @var{xsize}, mp_limb_t * @var{rs2p}, mp_size_t @var{rs2size}, const mp_limb_t * @var{s3p}, mp_size_t @var{s3size})
+Divide @{@var{rs2p}, @var{rs2size}@} by @{@var{s3p}, @var{s3size}@}, and
+write the quotient at @var{r1p}, with the exception of the most significant
+limb, which is returned. The remainder replaces the dividend at @var{rs2p}.
+
+In addition to an integer quotient, @var{xsize} fraction limbs are developed,
+and stored after the integral limbs. For most usages, @var{xsize} will be
+zero.
+
+It is required that @var{rs2size} is greater than or equal to @var{s3size}.
+It is required that the most significant bit of the divisor is set.
+
+If the quotient is not needed, pass @var{rs2p} + @var{s3size} as @var{r1p}.
+Aside from that special case, no overlap between arguments is permitted.
+
+Return the most significant limb of the quotient, either 0 or 1.
+
+The area at @var{r1p} needs to be @var{rs2size} @minus{} @var{s3size} +
+@var{xsize} limbs large.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_divrem_1 (mp_limb_t * @var{r1p}, mp_size_t @var{xsize}, mp_limb_t * @var{s2p}, mp_size_t @var{s2size}, mp_limb_t @var{s3limb})
+Divide @{@var{s2p}, @var{s2size}@} by @var{s3limb}, and write the quotient
+at @var{r1p}. Return the remainder.
+
+In addition to an integer quotient, @var{xsize} fraction limbs are developed,
+and stored after the integral limbs. For most usages, @var{xsize} will be
+zero.
+
+The areas at @var{r1p} and @var{s2p} have to be identical or completely
+separate, not partially overlapping.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_divmod (mp_limb_t * @var{r1p}, mp_limb_t * @var{rs2p}, mp_size_t @var{rs2size}, const mp_limb_t * @var{s3p}, mp_size_t @var{s3size})
+@strong{This interface is obsolete. It will disappear from future releases.
+Use @code{mpn_divrem} in its stead.}
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_divmod_1 (mp_limb_t * @var{r1p}, mp_limb_t * @var{s2p}, mp_size_t @var{s2size}, mp_limb_t @var{s3limb})
+@strong{This interface is obsolete. It will disappear from future releases.
+Use @code{mpn_divrem_1} in its stead.}
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_mod_1 (mp_limb_t * @var{s1p}, mp_size_t @var{s1size}, mp_limb_t @var{s2limb})
+Divide @{@var{s1p}, @var{s1size}@} by @var{s2limb}, and return the remainder.
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_preinv_mod_1 (mp_limb_t * @var{s1p}, mp_size_t @var{s1size}, mp_limb_t @var{s2limb}, mp_limb_t @var{s3limb})
+@strong{This interface is obsolete. It will disappear from future releases.
+Use @code{mpn_mod_1} in its stead.}
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_bdivmod (mp_limb_t * @var{dest_ptr}, mp_limb_t * @var{s1p}, mp_size_t @var{s1size}, const mp_limb_t * @var{s2p}, mp_size_t @var{s2size}, unsigned long int @var{d})
+The function puts the low [@var{d}/@var{BITS_PER_MP_LIMB}] limbs of
+@var{q} =
+@{@var{s1p}, @var{s1size}@}/@{@var{s2p}, @var{s2size}@}
+mod 2^@var{d}
+at @var{dest_ptr},
+and returns the high @var{d} mod @var{BITS_PER_MP_LIMB} bits of @var{q}.
+
+@{@var{s1p}, @var{s1size}@} - @var{q} * @{@var{s2p}, @var{s2size}@}
+mod 2^(@var{s1size}*@var{BITS_PER_MP_LIMB})
+is placed at @var{s1p}.
+Since the low [@var{d}/@var{BITS_PER_MP_LIMB}] limbs of
+this difference are zero, it is possible to overwrite the low limbs at
+@var{s1p} with this difference,
+provided @var{dest_ptr} <= @var{s1p}.
+
+This function requires that @var{s1size} * @var{BITS_PER_MP_LIMB} >= @var{D},
+and that @{@var{s2p}, @var{s2size}@} is odd.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_lshift (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src_ptr}, mp_size_t @var{src_size}, unsigned long int @var{count})
+Shift @{@var{src_ptr}, @var{src_size}@} @var{count} bits to the left, and
+write the @var{src_size} least significant limbs of the result to
+@var{dest_ptr}. @var{count} might be in the range 1 to n @minus{} 1, on an
+n-bit machine. The bits shifted out to the left are returned.
+
+Overlapping of the destination space and the source space is allowed in this
+function, provided @var{dest_ptr} >= @var{src_ptr}.
+
+This function is written in assembly for most targets.
+@end deftypefun
+
+@deftypefun mp_limp_t mpn_rshift (mp_limb_t * @var{dest_ptr}, const mp_limb_t * @var{src_ptr}, mp_size_t @var{src_size}, unsigned long int @var{count})
+Shift @{@var{src_ptr}, @var{src_size}@} @var{count} bits to the right, and
+write the @var{src_size} most significant limbs of the result to
+@var{dest_ptr}. @var{count} might be in the range 1 to n @minus{} 1, on an
+n-bit machine. The bits shifted out to the right are returned.
+
+Overlapping of the destination space and the source space is allowed in this
+function, provided @var{dest_ptr} <= @var{src_ptr}.
+
+This function is written in assembly for most targets.
+@end deftypefun
+
+@deftypefun int mpn_cmp (const mp_limb_t * @var{src1_ptr}, const mp_limb_t * @var{src2_ptr}, mp_size_t @var{size})
+Compare @{@var{src1_ptr}, @var{size}@} and @{@var{src2_ptr}, @var{size}@} and
+return a positive value if src1 > src2, 0 of they are equal, and a negative
+value if src1 < src2.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_gcd (mp_limb_t * @var{dest_ptr}, mp_limb_t * @var{src1_ptr}, mp_size_t @var{src1_size}, mp_limb_t * @var{src2_ptr}, mp_size_t @var{src2_size})
+Puts at @var{dest_ptr} the greatest common divisor of @{@var{src1_ptr},
+@var{src1_size}@} and @{@var{src2_ptr}, @var{src2_size}@}; both source
+operands are destroyed by the operation. The size in limbs of the greatest
+common divisor is returned.
+
+@{@var{src1_ptr}, @var{src1_size}@} must be odd, and @{@var{src2_ptr},
+@var{src2_size}@} must have at least as many bits as @{@var{src1_ptr},
+@var{src1_size}@}.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun mp_limb_t mpn_gcd_1 (const mp_limb_t * @var{src1_ptr}, mp_size_t @var{src1_size}, mp_limb_t @var{src2_limb})
+Return the greatest common divisor of @{@var{src1_ptr}, @var{src1_size}@}
+and @var{src2_limb}, where @var{src2_limb} (as well as @var{src1_size})
+must be different from 0.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_gcdext (mp_limb_t * @var{r1p}, mp_limb_t * @var{r2p}, mp_limb_t * @var{s1p}, mp_size_t @var{s1size}, mp_limb_t * @var{s2p}, mp_size_t @var{s2size})
+Puts at @var{r1p} the greatest common divisor of @{@var{s1p}, @var{s1size}@}
+and @{@var{s2p}, @var{s2size}@}. The first cofactor is written at
+@var{r2p}. Both source operands are destroyed by the operation. The size
+in limbs of the greatest common divisor is returned.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun mp_size_t mpn_sqrtrem (mp_limb_t * @var{r1p}, mp_limb_t * @var{r2p}, const mp_limb_t * @var{sp}, mp_size_t @var{size})
+Compute the square root of @{@var{sp}, @var{size}@} and put the result at
+@var{r1p}. Write the remainder at @var{r2p}, unless @var{r2p} is NULL.
+
+Return the size of the remainder, whether @var{r2p} was NULL or non-NULL.
+Iff the operand was a perfect square, the return value will be 0.
+
+The areas at @var{r1p} and @var{sp} have to be distinct. The areas at
+@var{r2p} and @var{sp} have to be identical or completely separate, not
+partially overlapping.
+
+@ifinfo
+The area at @var{r1p} needs to have space for ceil(@var{size}/2) limbs.
+@end ifinfo
+@iftex
+@tex
+The area at @var{r1p} needs to have space for $\lceil@var{size}/2\rceil$ limbs.
+@end tex
+@end iftex
+The area at @var{r2p} needs to be @var{size} limbs large.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun mp_size_t mpn_get_str (unsigned char *@var{str}, int @var{base}, mp_limb_t * @var{s1p}, mp_size_t @var{s1size})
+Convert @{@var{s1p}, @var{s1size}@} to a raw unsigned char array in base
+@var{base}. The string is not in ASCII; to convert it to printable format,
+add the ASCII codes for @samp{0} or @samp{A}, depending on the base and
+range. There may be leading zeros in the string.
+
+The area at @var{s1p} is clobbered.
+
+Return the number of characters in @var{str}.
+
+The area at @var{str} has to have space for the largest possible number
+represented by a @var{s1size} long limb array, plus one extra character.
+@end deftypefun
+
+@deftypefun mp_size_t mpn_set_str (mp_limb_t * @var{r1p}, const char *@var{str}, size_t {strsize}, int @var{base})
+Convert the raw unsigned char array at @var{str} of length @var{strsize} to
+a limb array @{@var{s1p}, @var{s1size}@}. The base of @var{str} is
+@var{base}.
+
+Return the number of limbs stored in @var{r1p}.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpn_scan0 (const mp_limb_t * @var{s1p}, unsigned long int @var{bit})
+Scan @var{s1p} from bit position @var{bit} for the next clear bit.
+
+It is required that there be a clear bit within the area at @var{s1p} at or
+beyond bit position @var{bit}, so that the function has something to return.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun {unsigned long int} mpn_scan1 (const mp_limb_t * @var{s1p}, unsigned long int @var{bit})
+Scan @var{s1p} from bit position @var{bit} for the next set bit.
+
+It is required that there be a set bit within the area at @var{s1p} at or
+beyond bit position @var{bit}, so that the function has something to return.
+
+@strong{This interface is preliminary. It might change incompatibly in
+future revisions.}
+@end deftypefun
+
+@deftypefun void mpn_random2 (mp_limb_t * @var{r1p}, mp_size_t @var{r1size})
+Generate a random number of length @var{r1size} with long strings of zeros
+and ones in the binary representation, and store it at @var{r1p}.
+
+The generated random numbers are intended for testing the correctness of the
+implementation of the @code{mpn} routines.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpn_popcount (const mp_limb_t * @var{s1p}, unsigned long int @var{size})
+Count the number of set bits in @{@var{s1p}, @var{size}@}.
+@end deftypefun
+
+@deftypefun {unsigned long int} mpn_hamdist (const mp_limb_t * @var{s1p}, const mp_limb_t * @var{s2p}, unsigned long int @var{size})
+Compute the hamming distance between @{@var{s1p}, @var{size}@} and
+@{@var{s2p}, @var{size}@}.
+@end deftypefun
+
+@deftypefun int mpn_perfect_square_p (const mp_limb_t * @var{s1p}, mp_size_t @var{size})
+Return non-zero iff @{@var{s1p}, @var{size}@} is a perfect square.
+@end deftypefun
+
+
+@node BSD Compatible Functions, Custom Allocation, Low-level Functions, Top
+@comment node-name, next, previous, up
+@chapter Berkeley MP Compatible Functions
+@cindex BSD MP compatible functions
+
+These functions are intended to be fully compatible with the Berkeley MP
+library which is available on many BSD derived U*ix systems.
+
+The original Berkeley MP library has a usage restriction: you cannot use the
+same variable as both source and destination in a single function call. The
+compatible functions in GNU MP do not share this restriction---inputs and
+outputs may overlap.
+
+It is not recommended that new programs are written using these functions.
+Apart from the incomplete set of functions, the interface for initializing
+@code{MINT} objects is more error prone, and the @code{pow} function collides
+with @code{pow} in @file{libm.a}.
+
+@cindex @file{mp.h}
+Include the header @file{mp.h} to get the definition of the necessary types
+and functions. If you are on a BSD derived system, make sure to include GNU
+@file{mp.h} if you are going to link the GNU @file{libmp.a} to you program.
+This means that you probably need to give the -I<dir> option to the compiler,
+where <dir> is the directory where you have GNU @file{mp.h}.
+
+@deftypefun {MINT *} itom (signed short int @var{initial_value})
+Allocate an integer consisting of a @code{MINT} object and dynamic limb space.
+Initialize the integer to @var{initial_value}. Return a pointer to the
+@code{MINT} object.
+@end deftypefun
+
+@deftypefun {MINT *} xtom (char *@var{initial_value})
+Allocate an integer consisting of a @code{MINT} object and dynamic limb space.
+Initialize the integer from @var{initial_value}, a hexadecimal, '\0'-terminate
+C string. Return a pointer to the @code{MINT} object.
+@end deftypefun
+
+@deftypefun void move (MINT *@var{src}, MINT *@var{dest})
+Set @var{dest} to @var{src} by copying. Both variables must be previously
+initialized.
+@end deftypefun
+
+@deftypefun void madd (MINT *@var{src_1}, MINT *@var{src_2}, MINT *@var{destination})
+Add @var{src_1} and @var{src_2} and put the sum in @var{destination}.
+@end deftypefun
+
+@deftypefun void msub (MINT *@var{src_1}, MINT *@var{src_2}, MINT *@var{destination})
+Subtract @var{src_2} from @var{src_1} and put the difference in
+@var{destination}.
+@end deftypefun
+
+@deftypefun void mult (MINT *@var{src_1}, MINT *@var{src_2}, MINT *@var{destination})
+Multiply @var{src_1} and @var{src_2} and put the product in
+@var{destination}.
+@end deftypefun
+
+@deftypefun void mdiv (MINT *@var{dividend}, MINT *@var{divisor}, MINT *@var{quotient}, MINT *@var{remainder})
+@deftypefunx void sdiv (MINT *@var{dividend}, signed short int @var{divisor}, MINT *@var{quotient}, signed short int *@var{remainder})
+Set @var{quotient} to @var{dividend}/@var{divisor}, and @var{remainder} to
+@var{dividend} mod @var{divisor}. The quotient is rounded towards zero; the
+remainder has the same sign as the dividend unless it is zero.
+
+Some implementations of these functions work differently---or not at all---for
+negative arguments.
+@end deftypefun
+
+@deftypefun void msqrt (MINT *@var{operand}, MINT *@var{root}, MINT *@var{remainder})
+@ifinfo
+Set @var{root} to the truncated integer part of the square root of
+@var{operand}. Set @var{remainder} to
+@var{operand}@minus{}@var{root}*@var{root},
+@end ifinfo
+@iftex
+@tex
+Set @var{root} to $\lfloor\sqrt{@var{operand}}\rfloor$, like
+@code{mpz_sqrt}. Set @var{remainder} to $(operand - root^2)$,
+@end tex
+@end iftex
+(i.e., zero if @var{operand} is a perfect square).
+
+If @var{root} and @var{remainder} are the same variable, the results are
+undefined.
+@end deftypefun
+
+@deftypefun void pow (MINT *@var{base}, MINT *@var{exp}, MINT *@var{mod}, MINT *@var{dest})
+Set @var{dest} to (@var{base} raised to @var{exp}) modulo @var{mod}.
+@end deftypefun
+
+@deftypefun void rpow (MINT *@var{base}, signed short int @var{exp}, MINT *@var{dest})
+Set @var{dest} to @var{base} raised to @var{exp}.
+@end deftypefun
+
+@deftypefun void gcd (MINT *@var{operand1}, MINT *@var{operand2}, MINT *@var{res})
+Set @var{res} to the greatest common divisor of @var{operand1} and
+@var{operand2}.
+@end deftypefun
+
+@deftypefun int mcmp (MINT *@var{operand1}, MINT *@var{operand2})
+Compare @var{operand1} and @var{operand2}. Return a positive value if
+@var{operand1} > @var{operand2}, zero if @var{operand1} =
+@var{operand2}, and a negative value if @var{operand1} < @var{operand2}.
+@end deftypefun
+
+@deftypefun void min (MINT *@var{dest})
+Input a decimal string from @code{stdin}, and put the read integer in
+@var{dest}. SPC and TAB are allowed in the number string, and are ignored.
+@end deftypefun
+
+@deftypefun void mout (MINT *@var{src})
+Output @var{src} to @code{stdout}, as a decimal string. Also output a newline.
+@end deftypefun
+
+@deftypefun {char *} mtox (MINT *@var{operand})
+Convert @var{operand} to a hexadecimal string, and return a pointer to the
+string. The returned string is allocated using the default memory allocation
+function, @code{malloc} by default.
+@end deftypefun
+
+@deftypefun void mfree (MINT *@var{operand})
+De-allocate, the space used by @var{operand}. @strong{This function should
+only be passed a value returned by @code{itom} or @code{xtom}.}
+@end deftypefun
+
+@node Custom Allocation, Contributors, BSD Compatible Functions, Top
+@comment node-name, next, previous, up
+@chapter Custom Allocation
+
+By default, the MP functions use @code{malloc}, @code{realloc}, and
+@code{free} for memory allocation. If @code{malloc} or @code{realloc} fails,
+the MP library terminates execution after printing a fatal error message to
+standard error.
+
+For some applications, you may wish to allocate memory in other ways, or you
+may not want to have a fatal error when there is no more memory available. To
+accomplish this, you can specify alternative memory allocation functions.
+
+@deftypefun void mp_set_memory_functions (@* void *(*@var{alloc_func_ptr}) (size_t), @* void *(*@var{realloc_func_ptr}) (void *, size_t, size_t), @* void (*@var{free_func_ptr}) (void *, size_t))
+Replace the current allocation functions from the arguments. If an argument
+is NULL, the corresponding default function is retained.
+
+@strong{Make sure to call this function in such a way that there are no active
+MP objects that were allocated using the previously active allocation
+function! Usually, that means that you have to call this function before any
+other MP function.}
+@end deftypefun
+
+The functions you supply should fit the following declarations:
+
+@deftypefun {void *} allocate_function (size_t @var{alloc_size})
+This function should return a pointer to newly allocated space with at least
+@var{alloc_size} storage units.
+@end deftypefun
+
+@deftypefun {void *} reallocate_function (void *@var{ptr}, size_t @var{old_size}, size_t @var{new_size})
+This function should return a pointer to newly allocated space of at least
+@var{new_size} storage units, after copying at least the first @var{old_size}
+storage units from @var{ptr}. It should also de-allocate the space at
+@var{ptr}.
+
+You can assume that the space at @var{ptr} was formerly returned from
+@code{allocate_function} or @code{reallocate_function}, for a request for
+@var{old_size} storage units.
+@end deftypefun
+
+@deftypefun void deallocate_function (void *@var{ptr}, size_t @var{size})
+De-allocate the space pointed to by @var{ptr}.
+
+You can assume that the space at @var{ptr} was formerly returned from
+@code{allocate_function} or @code{reallocate_function}, for a request for
+@var{size} storage units.
+@end deftypefun
+
+(A @dfn{storage unit} is the unit in which the @code{sizeof} operator returns
+the size of an object, normally an 8 bit byte.)
+
+
+@node Contributors, References, Custom Allocation, Top
+@comment node-name, next, previous, up
+@unnumbered Contributors
+
+I would like to thank Gunnar Sjoedin and Hans Riesel for their help with
+mathematical problems, Richard Stallman for his help with design issues and
+for revising the first version of this manual, Brian Beuning and Doug Lea for
+their testing of early versions of the library.
+
+John Amanatides of York University in Canada contributed the function
+@code{mpz_probab_prime_p}.
+
+Paul Zimmermann of Inria sparked the development of GMP 2, with his
+comparisons between bignum packages.
+
+Ken Weber (Kent State University, Universidade Federal do Rio Grande do Sul)
+contributed @code{mpz_gcd}, @code{mpz_divexact}, @code{mpn_gcd}, and
+@code{mpn_bdivmod}, partially supported by CNPq (Brazil) grant 301314194-2.
+
+Per Bothner of Cygnus Support helped to set up MP to use Cygnus' configure.
+He has also made valuable suggestions and tested numerous intermediary
+releases.
+
+Joachim Hollman was involved in the design of the @code{mpf} interface, and in
+the @code{mpz} design revisions for version 2.
+
+Bennet Yee contributed the functions @code{mpz_jacobi} and
+@code{mpz_legendre}.
+
+Andreas Schwab contributed the files @file{mpn/m68k/lshift.S} and
+@file{mpn/m68k/rshift.S}.
+
+The development of floating point functions of GNU MP 2, were supported in
+part by the ESPRIT-BRA (Basic Research Activities) 6846 project POSSO
+(POlynomial System SOlving).
+
+GNU MP 2 was finished and released by TMG Datakonsult, Sodermannagatan 5, 116
+23 STOCKHOLM, SWEDEN, in cooperation with the IDA Center for Computing
+Sciences, USA.
+
+
+@node References, , Contributors, Top
+@comment node-name, next, previous, up
+@unnumbered References
+
+@itemize @bullet
+
+@item
+Donald E. Knuth, "The Art of Computer Programming", vol 2,
+"Seminumerical Algorithms", 2nd edition, Addison-Wesley, 1981.
+
+@item
+John D. Lipson, "Elements of Algebra and Algebraic Computing",
+The Benjamin Cummings Publishing Company Inc, 1981.
+
+@item
+Richard M. Stallman, "Using and Porting GCC", Free Software Foundation,
+1995.
+
+@item
+Peter L. Montgomery, "Modular Multiplication Without Trial Division", in
+Mathematics of Computation, volume 44, number 170, April 1985.
+
+@item
+Torbjorn Granlund and Peter L. Montgomery, "Division by Invariant
+Integers using Multiplication", in Proceedings of the SIGPLAN
+PLDI'94 Conference, June 1994.
+
+@item
+Tudor Jebelean,
+"An algorithm for exact division",
+Journal of Symbolic Computation,
+v. 15, 1993, pp. 169-180.
+
+@item
+Kenneth Weber, "The accelerated integer GCD algorithm",
+ACM Transactions on Mathematical Software,
+v. 21 (March), 1995, pp. 111-122.
+@end itemize
+
+@node Concept Index, , , Top
+@comment node-name, next, previous, up
+@unnumbered Concept Index
+@printindex cp
+
+@node Function Index, , , Top
+@comment node-name, next, previous, up
+@unnumbered Function and Type Index
+@printindex fn
+
+
+@contents
+@bye
diff --git a/gnu/lib/libgmp/insert-double.c b/gnu/lib/libgmp/insert-double.c
new file mode 100644
index 0000000..1ce2571
--- /dev/null
+++ b/gnu/lib/libgmp/insert-double.c
@@ -0,0 +1,70 @@
+/* __gmp_insert_double -- convert from array of mp_limb_t to double.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef XDEBUG
+#undef _GMP_IEEE_FLOATS
+#endif
+
+#ifndef _GMP_IEEE_FLOATS
+#define _GMP_IEEE_FLOATS 0
+#endif
+
+double
+#if __STDC__
+__gmp_scale2 (double d, int exp)
+#else
+__gmp_scale2 (d, exp)
+ double d;
+ int exp;
+#endif
+{
+#if _GMP_IEEE_FLOATS
+ {
+ union ieee_double_extract x;
+ x.d = d;
+ x.s.exp += exp;
+ return x.d;
+ }
+#else
+ {
+ double factor, r;
+
+ factor = 2.0;
+ if (exp < 0)
+ {
+ factor = 0.5;
+ exp = -exp;
+ }
+ r = d;
+ while (exp != 0)
+ {
+ if ((exp & 1) != 0)
+ r *= factor;
+ factor *= factor;
+ exp >>= 1;
+ }
+ return r;
+ }
+#endif
+}
diff --git a/gnu/lib/libgmp/install.sh b/gnu/lib/libgmp/install.sh
new file mode 100755
index 0000000..5871924
--- /dev/null
+++ b/gnu/lib/libgmp/install.sh
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# 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.
+#
+
+
+# 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=:
+ 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/gnu/lib/libgmp/itom.c b/gnu/lib/libgmp/itom.c
new file mode 100644
index 0000000..64502fc
--- /dev/null
+++ b/gnu/lib/libgmp/itom.c
@@ -0,0 +1,53 @@
+/* itom -- BSD compatible allocate and initiate a MINT.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+MINT *
+#ifdef __STDC__
+itom (signed short int n)
+#else
+itom (n)
+ short int n;
+#endif
+{
+ MINT *x;
+ mp_ptr xp;
+
+ x = (MINT *) (*_mp_allocate_func) (sizeof (MINT));
+ x->alloc = 1;
+ x->d = xp = (mp_ptr) (*_mp_allocate_func) (x->alloc * BYTES_PER_MP_LIMB);
+ if (n > 0)
+ {
+ x->size = 1;
+ xp[0] = n;
+ }
+ else if (n < 0)
+ {
+ x->size = -1;
+ xp[0] = -n;
+ }
+ else
+ x->size = 0;
+
+ return x;
+}
diff --git a/gnu/lib/libgmp/longlong.h b/gnu/lib/libgmp/longlong.h
new file mode 100644
index 0000000..382fcc0
--- /dev/null
+++ b/gnu/lib/libgmp/longlong.h
@@ -0,0 +1,1404 @@
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file 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 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this file; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype.
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types.
+ DItype, UDItype -- Signed and unsigned 64 bit types.
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
+ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+#if defined (__GNUC__) && !defined (NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5
+ addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5
+ subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 46
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UDItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UDItype __udiv_qrnnd ();
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+#endif /* __alpha */
+
+#if defined (__arm__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5
+ adc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5
+ sbc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm
+ mov %|r0, %2, lsr #16
+ mov %|r2, %3, lsr #16
+ bic %|r1, %2, %|r0, lsl #16
+ bic %|r2, %3, %|r2, lsl #16
+ mul %1, %|r1, %|r2
+ mul %|r2, %|r0, %|r2
+ mul %|r1, %0, %|r1
+ mul %0, %|r0, %0
+ adds %|r1, %|r2, %|r1
+ addcs %0, %0, #65536
+ adds %1, %1, %|r1, lsl #16
+ adc %0, %0, %|r1, lsr #16" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1", "r2")
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1
+ addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1
+ subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
+ "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
+ "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
+ "0" ((USItype)0))
+#endif
+
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %4,%5,%1
+ addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %4,%5,%1
+ subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+ } while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#endif /* LONGLONG_STANDALONE */
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ "ldi 1,%0
+ extru,= %1,15,16,%%r0 ; Bits 31..16 zero?
+ extru,tr %1,15,16,%1 ; No. Shift down, skip add.
+ ldo 16(%0),%0 ; Yes. Perform add.
+ extru,= %1,23,8,%%r0 ; Bits 15..8 zero?
+ extru,tr %1,23,8,%1 ; No. Shift down, skip add.
+ ldo 8(%0),%0 ; Yes. Perform add.
+ extru,= %1,27,4,%%r0 ; Bits 7..4 zero?
+ extru,tr %1,27,4,%1 ; No. Shift down, skip add.
+ ldo 4(%0),%0 ; Yes. Perform add.
+ extru,= %1,29,2,%%r0 ; Bits 3..2 zero?
+ extru,tr %1,29,2,%1 ; No. Shift down, skip add.
+ ldo 2(%0),%0 ; Yes. Perform add.
+ extru %1,30,1,%1 ; Extract bit 1.
+ sub %0,%1,%0 ; Subtract it.
+ " : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
+ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
+ } while (0)
+#endif
+
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%1
+ adcl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1
+ sbbl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "rm" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define count_trailing_zeros(count, x) \
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+#if defined (__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined (__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+#endif /* i960mx */
+#endif /* i960 */
+
+#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1
+ addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1
+ subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
+ : "od" ((USItype)(x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#else /* not mc68020 */
+#define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm
+ move%.l %5,%3
+ move%.l %2,%0
+ move%.w %3,%1
+ swap %3
+ swap %0
+ mulu %2,%1
+ mulu %3,%0
+ mulu %2,%3
+ swap %2
+ mulu %5,%2
+ add%.l %3,%2
+ jcc 1f
+ add%.l %#0x10000,%0
+1: move%.l %2,%3
+ clr%.w %2
+ swap %2
+ swap %3
+ clr%.w %3
+ add%.l %3,%1
+ addx%.l %2,%0
+ | End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+#endif /* mc68000 */
+
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5
+ addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5
+ subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("mulu.d %0,%1,%2" \
+ : "=r" (__xx.__ll) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ USItype __q; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q) \
+ : "r" (__xx.__ll), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); (q) = __q; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+#if defined (__mips__) && W_TYPE_SIZE == 32
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3
+ mflo %0
+ mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips__ */
+
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3
+ mflo %0
+ mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips__ */
+
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+#define count_trailing_zeros(count,x) \
+ do {
+ __asm__ ("ffsd %2,%0" \
+ : "=r" ((USItype) (count)) \
+ : "0" ((USItype) 0), \
+ "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#if defined (_ARCH_PPC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" ((USItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((USItype)(xh)), \
+ "=q" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
+ "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
+#define UDIV_TIME 100
+#endif
+#endif /* Power architecture variants. */
+
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1
+ addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1
+ subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("movw %1,%R0
+ uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#endif /* __pyr__ */
+
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5
+ ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5
+ se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ( \
+ "s r2,r2
+ mts r10,%2
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ m r2,%3
+ cas %0,r2,r0
+ mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
+ (ph) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+#if defined (__sh2__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ( \
+ "dmulu.l %2,%3
+ sts macl,%1
+ sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1
+ addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1
+ subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#if defined (__sparc_v8__)
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#define UDIV_TIME 25
+#endif /* SUPERSPARC */
+#else /* ! __sparc_v8__ */
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd
+ wr %%g0,%2,%%y ! Not a delayed write for sparclite
+ tst %%g0
+ divscc %3,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%%g1
+ divscc %%g1,%4,%0
+ rd %%y,%1
+ bl,a 1f
+ add %1,%4,%1
+1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
+ : "r" ((USItype)(count)))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm
+ wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr
+ sra %3,31,%%g2 ! Don't move this insn
+ and %2,%%g2,%%g2 ! Don't move this insn
+ andcc %%g0,0,%%g1 ! Don't move this insn
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,%3,%%g1
+ mulscc %%g1,0,%%g1
+ add %%g1,%%g2,%0
+ rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#define UDIV_TIME 140
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+#if defined (__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1
+ adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1
+ sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.ll), "g" (d)); \
+ } while (0)
+#endif /* __vax__ */
+
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __xx; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+
+
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __m0 = (u), __m1 = (v); \
+ umul_ppmm (__w1, w0, __m0, __m1); \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+extern
+#ifdef __STDC__
+const
+#endif
+unsigned char __clz_tab[];
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
diff --git a/gnu/lib/libgmp/make.bat b/gnu/lib/libgmp/make.bat
new file mode 100755
index 0000000..2a79c48
--- /dev/null
+++ b/gnu/lib/libgmp/make.bat
@@ -0,0 +1,315 @@
+cd mpn
+copy msdos\asm-synt.h asm-synt.h
+copy bsd.h sysdep.h
+copy generic\inlines.c inlines.c
+copy x86\pentium\add_n.S add_n.S
+copy x86\pentium\addmul_1.S addmul_1.S
+copy generic\cmp.c cmp.c
+copy generic\divmod_1.c divmod_1.c
+copy generic\divrem.c divrem.c
+copy generic\divrem_1.c divrem_1.c
+copy generic\dump.c dump.c
+copy x86\pentium\lshift.S lshift.S
+copy generic\mod_1.c mod_1.c
+copy generic\mul.c mul.c
+copy x86\pentium\mul_1.S mul_1.S
+copy generic\mul_n.c mul_n.c
+copy generic\random2.c random2.c
+copy x86\pentium\rshift.S rshift.S
+copy generic\sqrtrem.c sqrtrem.c
+copy x86\pentium\sub_n.S sub_n.S
+copy x86\pentium\submul_1.S submul_1.S
+copy generic\get_str.c get_str.c
+copy generic\set_str.c set_str.c
+copy generic\scan0.c scan0.c
+copy generic\scan1.c scan1.c
+copy generic\popcount.c popcount.c
+copy generic\hamdist.c hamdist.c
+copy generic\gcd_1.c gcd_1.c
+copy generic\pre_mod_1.c pre_mod_1.c
+copy generic\perfsqr.c perfsqr.c
+copy generic\bdivmod.c bdivmod.c
+copy generic\gcd.c gcd.c
+copy generic\gcdext.c gcdext.c
+copy x86\gmp-mpar.h gmp-mpar.h
+cd ..
+
+cd mpbsd
+copy ..\mpz\add.c add.c
+copy ..\mpz\cmp.c cmp.c
+copy ..\mpz\gcd.c gcd.c
+copy ..\mpz\mul.c mul.c
+copy ..\mpz\pow_ui.c pow_ui.c
+copy ..\mpz\powm.c powm.c
+copy ..\mpz\sqrtrem.c sqrtrem.c
+copy ..\mpz\sub.c sub.c
+cd ..
+
+cd mpn
+gcc -c -I. -I.. -g -O mp_bases.c
+gcc -c -I. -I.. -g -O inlines.c
+gcc -E -I. -I.. -g -O add_n.S | grep -v '^#' >tmp-add_n.s
+gcc -c tmp-add_n.s -o add_n.o
+del tmp-add_n.s
+gcc -E -I. -I.. -g -O addmul_1.S | grep -v '^#' >tmp-addmul_1.s
+gcc -c tmp-addmul_1.s -o addmul_1.o
+del tmp-addmul_1.s
+gcc -c -I. -I.. -g -O cmp.c
+gcc -c -I. -I.. -g -O divmod_1.c
+gcc -c -I. -I.. -g -O divrem.c
+gcc -c -I. -I.. -g -O divrem_1.c
+gcc -c -I. -I.. -g -O dump.c
+gcc -E -I. -I.. -g -O lshift.S | grep -v '^#' >tmp-lshift.s
+gcc -c tmp-lshift.s -o lshift.o
+del tmp-lshift.s
+gcc -c -I. -I.. -g -O mod_1.c
+gcc -c -I. -I.. -g -O mul.c
+gcc -E -I. -I.. -g -O mul_1.S | grep -v '^#' >tmp-mul_1.s
+gcc -c tmp-mul_1.s -o mul_1.o
+del tmp-mul_1.s
+gcc -c -I. -I.. -g -O mul_n.c
+gcc -c -I. -I.. -g -O random2.c
+gcc -E -I. -I.. -g -O rshift.S | grep -v '^#' >tmp-rshift.s
+gcc -c tmp-rshift.s -o rshift.o
+del tmp-rshift.s
+gcc -c -I. -I.. -g -O sqrtrem.c
+gcc -E -I. -I.. -g -O sub_n.S | grep -v '^#' >tmp-sub_n.s
+gcc -c tmp-sub_n.s -o sub_n.o
+del tmp-sub_n.s
+gcc -E -I. -I.. -g -O submul_1.S | grep -v '^#' >tmp-submul_1.s
+gcc -c tmp-submul_1.s -o submul_1.o
+del tmp-submul_1.s
+gcc -c -I. -I.. -g -O get_str.c
+gcc -c -I. -I.. -g -O set_str.c
+gcc -c -I. -I.. -g -O scan0.c
+gcc -c -I. -I.. -g -O scan1.c
+gcc -c -I. -I.. -g -O popcount.c
+gcc -c -I. -I.. -g -O hamdist.c
+gcc -c -I. -I.. -g -O gcd_1.c
+gcc -c -I. -I.. -g -O pre_mod_1.c
+gcc -c -I. -I.. -g -O perfsqr.c
+gcc -c -I. -I.. -g -O bdivmod.c
+gcc -c -I. -I.. -g -O gcd.c
+gcc -c -I. -I.. -g -O gcdext.c
+del libmpn.a
+ar rc libmpn.a *.o
+cd ..
+
+cd mpz
+gcc -c -I. -I.. -I../mpn -g -O abs.c
+gcc -c -I. -I.. -I../mpn -g -O add.c
+gcc -c -I. -I.. -I../mpn -g -O add_ui.c
+gcc -c -I. -I.. -I../mpn -g -O and.c
+gcc -c -I. -I.. -I../mpn -g -O array_init.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_q.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_q_ui.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_qr.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_qr_ui.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_r.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_r_ui.c
+gcc -c -I. -I.. -I../mpn -g -O cdiv_ui.c
+gcc -c -I. -I.. -I../mpn -g -O clear.c
+gcc -c -I. -I.. -I../mpn -g -O clrbit.c
+gcc -c -I. -I.. -I../mpn -g -O cmp.c
+gcc -c -I. -I.. -I../mpn -g -O cmp_si.c
+gcc -c -I. -I.. -I../mpn -g -O cmp_ui.c
+gcc -c -I. -I.. -I../mpn -g -O com.c
+gcc -c -I. -I.. -I../mpn -g -O divexact.c
+gcc -c -I. -I.. -I../mpn -g -O fac_ui.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_q.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_q_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_q_ui.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_qr.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_qr_ui.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_r.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_r_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_r_ui.c
+gcc -c -I. -I.. -I../mpn -g -O fdiv_ui.c
+gcc -c -I. -I.. -I../mpn -g -O gcd.c
+gcc -c -I. -I.. -I../mpn -g -O gcd_ui.c
+gcc -c -I. -I.. -I../mpn -g -O gcdext.c
+gcc -c -I. -I.. -I../mpn -g -O get_d.c
+gcc -c -I. -I.. -I../mpn -g -O get_si.c
+gcc -c -I. -I.. -I../mpn -g -O get_str.c
+gcc -c -I. -I.. -I../mpn -g -O get_ui.c
+gcc -c -I. -I.. -I../mpn -g -O getlimbn.c
+gcc -c -I. -I.. -I../mpn -g -O hamdist.c
+gcc -c -I. -I.. -I../mpn -g -O init.c
+gcc -c -I. -I.. -I../mpn -g -O inp_raw.c
+gcc -c -I. -I.. -I../mpn -g -O inp_str.c
+gcc -c -I. -I.. -I../mpn -g -O invert.c
+gcc -c -I. -I.. -I../mpn -g -O ior.c
+gcc -c -I. -I.. -I../mpn -g -O iset.c
+gcc -c -I. -I.. -I../mpn -g -O iset_d.c
+gcc -c -I. -I.. -I../mpn -g -O iset_si.c
+gcc -c -I. -I.. -I../mpn -g -O iset_str.c
+gcc -c -I. -I.. -I../mpn -g -O iset_ui.c
+gcc -c -I. -I.. -I../mpn -g -O jacobi.c
+gcc -c -I. -I.. -I../mpn -g -O legendre.c
+gcc -c -I. -I.. -I../mpn -g -O mod.c
+gcc -c -I. -I.. -I../mpn -g -O mul.c
+gcc -c -I. -I.. -I../mpn -g -O mul_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O mul_ui.c
+gcc -c -I. -I.. -I../mpn -g -O neg.c
+gcc -c -I. -I.. -I../mpn -g -O out_raw.c
+gcc -c -I. -I.. -I../mpn -g -O out_str.c
+gcc -c -I. -I.. -I../mpn -g -O perfsqr.c
+gcc -c -I. -I.. -I../mpn -g -O popcount.c
+gcc -c -I. -I.. -I../mpn -g -O pow_ui.c
+gcc -c -I. -I.. -I../mpn -g -O powm.c
+gcc -c -I. -I.. -I../mpn -g -O powm_ui.c
+gcc -c -I. -I.. -I../mpn -g -O pprime_p.c
+gcc -c -I. -I.. -I../mpn -g -O random.c
+gcc -c -I. -I.. -I../mpn -g -O random2.c
+gcc -c -I. -I.. -I../mpn -g -O realloc.c
+gcc -c -I. -I.. -I../mpn -g -O scan0.c
+gcc -c -I. -I.. -I../mpn -g -O scan1.c
+gcc -c -I. -I.. -I../mpn -g -O set.c
+gcc -c -I. -I.. -I../mpn -g -O set_d.c
+gcc -c -I. -I.. -I../mpn -g -O set_f.c
+gcc -c -I. -I.. -I../mpn -g -O set_q.c
+gcc -c -I. -I.. -I../mpn -g -O set_si.c
+gcc -c -I. -I.. -I../mpn -g -O set_str.c
+gcc -c -I. -I.. -I../mpn -g -O set_ui.c
+gcc -c -I. -I.. -I../mpn -g -O setbit.c
+gcc -c -I. -I.. -I../mpn -g -O size.c
+gcc -c -I. -I.. -I../mpn -g -O sizeinbase.c
+gcc -c -I. -I.. -I../mpn -g -O sqrt.c
+gcc -c -I. -I.. -I../mpn -g -O sqrtrem.c
+gcc -c -I. -I.. -I../mpn -g -O sub.c
+gcc -c -I. -I.. -I../mpn -g -O sub_ui.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_q.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_q_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_q_ui.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_qr.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_qr_ui.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_r.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_r_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O tdiv_r_ui.c
+gcc -c -I. -I.. -I../mpn -g -O ui_pow_ui.c
+del libmpz.a
+ar rc libmpz.a *.o
+cd ..
+
+cd mpf
+gcc -c -I. -I.. -I../mpn -g -O abs.c
+gcc -c -I. -I.. -I../mpn -g -O add.c
+gcc -c -I. -I.. -I../mpn -g -O add_ui.c
+gcc -c -I. -I.. -I../mpn -g -O clear.c
+gcc -c -I. -I.. -I../mpn -g -O cmp.c
+gcc -c -I. -I.. -I../mpn -g -O cmp_si.c
+gcc -c -I. -I.. -I../mpn -g -O cmp_ui.c
+gcc -c -I. -I.. -I../mpn -g -O div.c
+gcc -c -I. -I.. -I../mpn -g -O div_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O div_ui.c
+gcc -c -I. -I.. -I../mpn -g -O dump.c
+gcc -c -I. -I.. -I../mpn -g -O eq.c
+gcc -c -I. -I.. -I../mpn -g -O get_d.c
+gcc -c -I. -I.. -I../mpn -g -O get_prc.c
+gcc -c -I. -I.. -I../mpn -g -O get_str.c
+gcc -c -I. -I.. -I../mpn -g -O init.c
+gcc -c -I. -I.. -I../mpn -g -O init2.c
+gcc -c -I. -I.. -I../mpn -g -O inp_str.c
+gcc -c -I. -I.. -I../mpn -g -O iset.c
+gcc -c -I. -I.. -I../mpn -g -O iset_d.c
+gcc -c -I. -I.. -I../mpn -g -O iset_si.c
+gcc -c -I. -I.. -I../mpn -g -O iset_str.c
+gcc -c -I. -I.. -I../mpn -g -O iset_ui.c
+gcc -c -I. -I.. -I../mpn -g -O mul.c
+gcc -c -I. -I.. -I../mpn -g -O mul_2exp.c
+gcc -c -I. -I.. -I../mpn -g -O mul_ui.c
+gcc -c -I. -I.. -I../mpn -g -O neg.c
+gcc -c -I. -I.. -I../mpn -g -O out_str.c
+gcc -c -I. -I.. -I../mpn -g -O random2.c
+gcc -c -I. -I.. -I../mpn -g -O reldiff.c
+gcc -c -I. -I.. -I../mpn -g -O set.c
+gcc -c -I. -I.. -I../mpn -g -O set_d.c
+gcc -c -I. -I.. -I../mpn -g -O set_dfl_prc.c
+gcc -c -I. -I.. -I../mpn -g -O set_prc.c
+gcc -c -I. -I.. -I../mpn -g -O set_prc_raw.c
+gcc -c -I. -I.. -I../mpn -g -O set_q.c
+gcc -c -I. -I.. -I../mpn -g -O set_si.c
+gcc -c -I. -I.. -I../mpn -g -O set_str.c
+gcc -c -I. -I.. -I../mpn -g -O set_ui.c
+gcc -c -I. -I.. -I../mpn -g -O set_z.c
+gcc -c -I. -I.. -I../mpn -g -O size.c
+gcc -c -I. -I.. -I../mpn -g -O sqrt.c
+gcc -c -I. -I.. -I../mpn -g -O sqrt_ui.c
+gcc -c -I. -I.. -I../mpn -g -O sub.c
+gcc -c -I. -I.. -I../mpn -g -O sub_ui.c
+gcc -c -I. -I.. -I../mpn -g -O ui_div.c
+gcc -c -I. -I.. -I../mpn -g -O ui_sub.c
+del libmpf.a
+ar cr libmpf.a *.o
+cd ..
+
+cd mpq
+gcc -c -I. -I.. -I../mpn -g -O add.c
+gcc -c -I. -I.. -I../mpn -g -O canonicalize.c
+gcc -c -I. -I.. -I../mpn -g -O clear.c
+gcc -c -I. -I.. -I../mpn -g -O cmp.c
+gcc -c -I. -I.. -I../mpn -g -O cmp_ui.c
+gcc -c -I. -I.. -I../mpn -g -O div.c
+gcc -c -I. -I.. -I../mpn -g -O equal.c
+gcc -c -I. -I.. -I../mpn -g -O get_d.c
+gcc -c -I. -I.. -I../mpn -g -O get_den.c
+gcc -c -I. -I.. -I../mpn -g -O get_num.c
+gcc -c -I. -I.. -I../mpn -g -O init.c
+gcc -c -I. -I.. -I../mpn -g -O inv.c
+gcc -c -I. -I.. -I../mpn -g -O mul.c
+gcc -c -I. -I.. -I../mpn -g -O neg.c
+gcc -c -I. -I.. -I../mpn -g -O set.c
+gcc -c -I. -I.. -I../mpn -g -O set_den.c
+gcc -c -I. -I.. -I../mpn -g -O set_num.c
+gcc -c -I. -I.. -I../mpn -g -O set_si.c
+gcc -c -I. -I.. -I../mpn -g -O set_ui.c
+gcc -c -I. -I.. -I../mpn -g -O set_z.c
+gcc -c -I. -I.. -I../mpn -g -O sub.c
+del libmpq.a
+ar cr libmpq.a *.o
+cd ..
+
+gcc -c -I. -Impn -I.. -g -O extract-double.c
+gcc -c -I. -Impn -I.. -g -O insert-double.c
+gcc -c -I. -Impn -I.. -g -O memory.c
+gcc -c -I. -Impn -I.. -g -O mp_clz_tab.c
+gcc -c -I. -Impn -I.. -g -O mp_set_fns.c
+gcc -c -I. -Impn -I.. -g -O stack-alloc.c
+gcc -c -I. -Impn -I.. -g -O version.c
+deltree/y tmpdir
+
+md tmpdir
+
+md tmpdir\mpn
+cd tmpdir\mpn
+ar x ../../mpn/libmpn.a
+cd ..\..
+
+md tmpdir\mpz
+cd tmpdir\mpz
+ar x ../../mpz/libmpz.a
+cd ..\..
+
+md tmpdir\mpq
+cd tmpdir\mpq
+ar x ../../mpq/libmpq.a
+cd ..\..
+
+md tmpdir\mpf
+cd tmpdir\mpf
+ar x ../../mpf/libmpf.a
+cd ..\..
+
+copy memory.o tmpdir
+copy mp_set_fns.o tmpdir
+copy mp_clz_tab.o tmpdir
+copy version.o tmpdir
+copy stack-alloc.o tmpdir
+
+cd tmpdir
+ar rc libgmp.a *.o */*.o
+ranlib libgmp.a
+cd ..
+
+move/y tmpdir\libgmp.a libgmp.a
+deltree/y tmpdir
diff --git a/gnu/lib/libgmp/mdiv.c b/gnu/lib/libgmp/mdiv.c
new file mode 100644
index 0000000..950aa50
--- /dev/null
+++ b/gnu/lib/libgmp/mdiv.c
@@ -0,0 +1,38 @@
+/* mdiv -- BSD compatible divide producing both remainder and quotient.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mdiv (const MINT *num, const MINT *den, MINT *quot, MINT *rem)
+#else
+mdiv (num, den, quot, rem)
+ const MINT *num;
+ const MINT *den;
+ MINT *quot;
+ MINT *rem;
+#endif
+
+#define COMPUTE_QUOTIENT
+#include "mpz_dmincl.c"
diff --git a/gnu/lib/libgmp/memory.c b/gnu/lib/libgmp/memory.c
new file mode 100644
index 0000000..9ee1da8
--- /dev/null
+++ b/gnu/lib/libgmp/memory.c
@@ -0,0 +1,97 @@
+/* Memory allocation routines.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifdef __NeXT__
+#define static
+#endif
+
+#if __STDC__
+void * (*_mp_allocate_func) (size_t) = _mp_default_allocate;
+void * (*_mp_reallocate_func) (void *, size_t, size_t)
+ = _mp_default_reallocate;
+void (*_mp_free_func) (void *, size_t) = _mp_default_free;
+#else
+void * (*_mp_allocate_func) () = _mp_default_allocate;
+void * (*_mp_reallocate_func) () = _mp_default_reallocate;
+void (*_mp_free_func) () = _mp_default_free;
+#endif
+
+/* Default allocation functions. In case of failure to allocate/reallocate
+ an error message is written to stderr and the program aborts. */
+
+void *
+#if __STDC__
+_mp_default_allocate (size_t size)
+#else
+_mp_default_allocate (size)
+ size_t size;
+#endif
+{
+ void *ret;
+
+ ret = malloc (size);
+ if (ret == 0)
+ {
+ perror ("cannot allocate in gmp");
+ abort ();
+ }
+
+ return ret;
+}
+
+void *
+#if __STDC__
+_mp_default_reallocate (void *oldptr, size_t old_size, size_t new_size)
+#else
+_mp_default_reallocate (oldptr, old_size, new_size)
+ void *oldptr;
+ size_t old_size;
+ size_t new_size;
+#endif
+{
+ void *ret;
+
+ ret = realloc (oldptr, new_size);
+ if (ret == 0)
+ {
+ perror ("cannot allocate in gmp");
+ abort ();
+ }
+
+ return ret;
+}
+
+void
+#if __STDC__
+_mp_default_free (void *blk_ptr, size_t blk_size)
+#else
+_mp_default_free (blk_ptr, blk_size)
+ void *blk_ptr;
+ size_t blk_size;
+#endif
+{
+ free (blk_ptr);
+}
diff --git a/gnu/lib/libgmp/mfree.c b/gnu/lib/libgmp/mfree.c
new file mode 100644
index 0000000..de4bee5
--- /dev/null
+++ b/gnu/lib/libgmp/mfree.c
@@ -0,0 +1,35 @@
+/* mfree -- BSD compatible mfree.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mfree (MINT *m)
+#else
+mfree (m)
+ MINT *m;
+#endif
+{
+ (*_mp_free_func) (m->d, m->alloc * BYTES_PER_MP_LIMB);
+ (*_mp_free_func) (m, sizeof (MINT));
+}
diff --git a/gnu/lib/libgmp/min.c b/gnu/lib/libgmp/min.c
new file mode 100644
index 0000000..2bc7d6d
--- /dev/null
+++ b/gnu/lib/libgmp/min.c
@@ -0,0 +1,64 @@
+/* min(MINT) -- Do decimal input from standard input and store result in
+ MINT.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+min (MINT *x)
+#else
+min (x)
+ MINT *x;
+#endif
+{
+ char *str;
+ size_t str_size;
+ size_t i;
+ int c;
+
+ str_size = 100;
+ str = (char *) (*_mp_allocate_func) (str_size);
+
+ for (i = 0; ; i++)
+ {
+ if (i >= str_size)
+ {
+ size_t old_str_size = str_size;
+ str_size = str_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_str_size, str_size);
+ }
+ c = getc (stdin);
+ if (!(isdigit(c) || c == ' ' || c == '\t'))
+ break;
+ str[i] = c;
+ }
+
+ ungetc (c, stdin);
+
+ str[i] = 0;
+ _mpz_set_str (x, str, 10);
+
+ (*_mp_free_func) (str, str_size);
+}
diff --git a/gnu/lib/libgmp/mkinstalldirs b/gnu/lib/libgmp/mkinstalldirs
new file mode 100755
index 0000000..cd1fe0a
--- /dev/null
+++ b/gnu/lib/libgmp/mkinstalldirs
@@ -0,0 +1,32 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/gnu/lib/libgmp/mout.c b/gnu/lib/libgmp/mout.c
new file mode 100644
index 0000000..7aeaa16
--- /dev/null
+++ b/gnu/lib/libgmp/mout.c
@@ -0,0 +1,42 @@
+/* mout(MINT) -- Do decimal output of MINT to standard output.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mout (const MINT *x)
+#else
+mout (x)
+ const MINT *x;
+#endif
+{
+ char *str;
+ size_t str_size;
+
+ str_size = ((size_t) (ABS (x->size) * BITS_PER_MP_LIMB
+ * __mp_bases[10].chars_per_bit_exactly)) + 3;
+ str = (char *) alloca (str_size);
+ _mpz_get_str (str, 10, x);
+ puts (str);
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/move-if-change b/gnu/lib/libgmp/move-if-change
new file mode 100755
index 0000000..ee9e355
--- /dev/null
+++ b/gnu/lib/libgmp/move-if-change
@@ -0,0 +1,15 @@
+#!/bin/sh
+if
+test -r $2
+then
+if
+cmp $1 $2 > /dev/null
+then
+echo $2 is unchanged
+rm -f $1
+else
+mv -f $1 $2
+fi
+else
+mv -f $1 $2
+fi
diff --git a/gnu/lib/libgmp/move.c b/gnu/lib/libgmp/move.c
new file mode 100644
index 0000000..82b9cc3
--- /dev/null
+++ b/gnu/lib/libgmp/move.c
@@ -0,0 +1,45 @@
+/* move -- BSD compatible assignment.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+move (const MINT *u, MINT *w)
+#else
+move (u, w)
+ const MINT *u;
+ MINT *w;
+#endif
+{
+ mp_size usize;
+ mp_size abs_usize;
+
+ usize = u->size;
+ abs_usize = ABS (usize);
+
+ if (w->alloc < abs_usize)
+ _mpz_realloc (w, abs_usize);
+
+ w->size = usize;
+ MPN_COPY (w->d, u->d, abs_usize);
+}
diff --git a/gnu/lib/libgmp/mp.h b/gnu/lib/libgmp/mp.h
new file mode 100644
index 0000000..830b26b
--- /dev/null
+++ b/gnu/lib/libgmp/mp.h
@@ -0,0 +1,141 @@
+/* mp.h -- Definitions for Berkeley compatible multiple precision functions.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#ifndef __MP_H__
+
+#ifndef __GNU_MP__
+#define __GNU_MP__ 2
+#define __need_size_t
+#include <stddef.h>
+#undef __need_size_t
+
+#if defined (__STDC__) || defined (__cplusplus)
+#define __gmp_const const
+#else
+#define __gmp_const
+#endif
+
+#if defined (__GNUC__)
+#define __gmp_inline __inline__
+#else
+#define __gmp_inline
+#endif
+
+#ifndef _EXTERN_INLINE
+#ifdef __GNUC__
+#define _EXTERN_INLINE extern __inline__
+#else
+#define _EXTERN_INLINE static
+#endif
+#endif
+
+#ifdef _SHORT_LIMB
+typedef unsigned int mp_limb_t;
+typedef int mp_limb_signed_t;
+#else
+#ifdef _LONG_LONG_LIMB
+typedef unsigned long long int mp_limb_t;
+typedef long long int mp_limb_signed_t;
+#else
+typedef unsigned long int mp_limb_t;
+typedef long int mp_limb_signed_t;
+#endif
+#endif
+
+typedef mp_limb_t * mp_ptr;
+typedef __gmp_const mp_limb_t * mp_srcptr;
+typedef int mp_size_t;
+typedef long int mp_exp_t;
+
+#ifndef __MP_SMALL__
+typedef struct
+{
+ mp_size_t _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the D field. */
+ mp_size_t _mp_size; /* abs(SIZE) is the number of limbs
+ the last field points to. If SIZE
+ is negative this is a negative
+ number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+#else
+typedef struct
+{
+ short int _mp_alloc; /* Number of *limbs* allocated and pointed
+ to by the D field. */
+ short int _mp_size; /* abs(SIZE) is the number of limbs
+ the last field points to. If SIZE
+ is negative this is a negative
+ number. */
+ mp_limb_t *_mp_d; /* Pointer to the limbs. */
+} __mpz_struct;
+#endif
+#endif /* __GNU_MP__ */
+
+/* User-visible types. */
+typedef __mpz_struct MINT;
+
+#ifdef __STDC__
+void mp_set_memory_functions (void *(*) (size_t),
+ void *(*) (void *, size_t, size_t),
+ void (*) (void *, size_t));
+MINT *itom (signed short int);
+MINT *xtom (const char *);
+void move (const MINT *, MINT *);
+void madd (const MINT *, const MINT *, MINT *);
+void msub (const MINT *, const MINT *, MINT *);
+void mult (const MINT *, const MINT *, MINT *);
+void mdiv (const MINT *, const MINT *, MINT *, MINT *);
+void sdiv (const MINT *, signed short int, MINT *, signed short int *);
+void msqrt (const MINT *, MINT *, MINT *);
+void pow (const MINT *, const MINT *, const MINT *, MINT *);
+void rpow (const MINT *, signed short int, MINT *);
+void gcd (const MINT *, const MINT *, MINT *);
+int mcmp (const MINT *, const MINT *);
+void min (MINT *);
+void mout (const MINT *);
+char *mtox (const MINT *);
+void mfree (MINT *);
+
+#else
+
+void mp_set_memory_functions ();
+MINT *itom ();
+MINT *xtom ();
+void move ();
+void madd ();
+void msub ();
+void mult ();
+void mdiv ();
+void sdiv ();
+void msqrt ();
+void pow ();
+void rpow ();
+void gcd ();
+int mcmp ();
+void min ();
+void mout ();
+char *mtox ();
+void mfree ();
+#endif
+
+#define __MP_H__
+#endif /* __MP_H__ */
diff --git a/gnu/lib/libgmp/mp_bpl.c b/gnu/lib/libgmp/mp_bpl.c
new file mode 100644
index 0000000..d817ac8
--- /dev/null
+++ b/gnu/lib/libgmp/mp_bpl.c
@@ -0,0 +1,4 @@
+#include "gmp.h"
+#include "gmp-impl.h"
+
+const int mp_bits_per_limb = BITS_PER_MP_LIMB;
diff --git a/gnu/lib/libgmp/mp_clz_tab.c b/gnu/lib/libgmp/mp_clz_tab.c
new file mode 100644
index 0000000..6fd7e90
--- /dev/null
+++ b/gnu/lib/libgmp/mp_clz_tab.c
@@ -0,0 +1,40 @@
+/* __clz_tab -- support for longlong.h
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#if 0
+#include "gmp.h"
+#include "gmp-impl.h"
+#endif
+
+#if 0
+const
+#endif
+unsigned char __clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
diff --git a/gnu/lib/libgmp/mp_set_fns.c b/gnu/lib/libgmp/mp_set_fns.c
new file mode 100644
index 0000000..35a462c
--- /dev/null
+++ b/gnu/lib/libgmp/mp_set_fns.c
@@ -0,0 +1,48 @@
+/* mp_set_memory_functions -- Set the allocate, reallocate, and free functions
+ for use by the mp package.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mp_set_memory_functions (void *(*alloc_func) (size_t),
+ void *(*realloc_func) (void *, size_t, size_t),
+ void (*free_func) (void *, size_t))
+#else
+mp_set_memory_functions (alloc_func, realloc_func, free_func)
+ void *(*alloc_func) ();
+ void *(*realloc_func) ();
+ void (*free_func) ();
+#endif
+{
+ if (alloc_func == 0)
+ alloc_func = _mp_default_allocate;
+ if (realloc_func == 0)
+ realloc_func = _mp_default_reallocate;
+ if (free_func == 0)
+ free_func = _mp_default_free;
+
+ _mp_allocate_func = alloc_func;
+ _mp_reallocate_func = realloc_func;
+ _mp_free_func = free_func;
+}
diff --git a/gnu/lib/libgmp/mpbsd/Makefile.in b/gnu/lib/libgmp/mpbsd/Makefile.in
new file mode 100644
index 0000000..a517c1a
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/Makefile.in
@@ -0,0 +1,84 @@
+# Makefile for GNU MP/mpbsd functions
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+CC = gcc
+
+# If you cross compile on a machine with the same sizes of the integral
+# types ("int", "long int", "short int", and "char") define this as the
+# local compiler. Otherwise, you need to look for the uses of LOCAL_CC below,
+# and handle those cases manually.
+LOCAL_CC = $(CC)
+CFLAGS = -g -O
+AR = ar
+SHELL = /bin/sh
+
+#### host and target specific makefile fragments come in here.
+###
+
+MPBSD_LINKS = add.c cmp.c gcd.c mul.c pow_ui.c powm.c sqrtrem.c sub.c
+MPBSD_SRCS = itom.c mdiv.c mfree.c min.c mout.c move.c mtox.c sdiv.c xtom.c \
+ realloc.c $(MPBSD_LINKS)
+
+MPBSD_OBJS = itom.o mdiv.o mfree.o min.o mout.o move.o mtox.o sdiv.o xtom.o \
+ realloc.o add.o cmp.o gcd.o mul.o pow_ui.o powm.o sqrtrem.o sub.o
+
+INCLUDES = -I. -I.. -I$(srcdir)/../mpz -I../mpn -I$(srcdir)/..
+
+libmpbsd.a: Makefile.in $(MPBSD_OBJS)
+ rm -f $@
+ $(AR) cr $@ $(MPBSD_OBJS)
+
+.c.o:
+ $(CC) -c $(INCLUDES) -DBERKELEY_MP $(CFLAGS) $(XCFLAGS) $<
+
+check:
+ true
+
+clean mostlyclean:
+ rm -f *.o libmpbsd.a
+distclean maintainer-clean: clean
+ rm -f Makefile config.status $(MPBSD_LINKS)
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h ../mpn/gmp-mparam.h
+L = $(srcdir)/../longlong.h
+
+itom.o: $(srcdir)/itom.c ../mp.h $(H)
+mdiv.o: $(srcdir)/mdiv.c ../mp.h $(H) $(L) $(srcdir)/../mpz/dmincl.c
+mfree.o: $(srcdir)/mfree.c ../mp.h $(H)
+min.o: $(srcdir)/min.c ../mp.h $(H)
+mout.o: $(srcdir)/mout.c ../mp.h $(H)
+move.o: $(srcdir)/move.c ../mp.h $(H)
+mtox.o: $(srcdir)/mtox.c ../mp.h $(H)
+sdiv.o: $(srcdir)/sdiv.c ../mp.h $(H) $(L)
+xtom.o: $(srcdir)/xtom.c ../mp.h $(H)
+add.o: $(srcdir)/../mpz/add.c $(H)
+cmp.o: $(srcdir)/../mpz/cmp.c $(H)
+gcd.o: $(srcdir)/../mpz/gcd.c $(H) $(L)
+mul.o: $(srcdir)/../mpz/mul.c $(H)
+pow_ui.o: $(srcdir)/../mpz/pow_ui.c $(H) $(L)
+powm.o: $(srcdir)/../mpz/powm.c $(H) $(L)
+realloc.o: $(srcdir)/realloc.c $(H)
+sqrtrem.o: $(srcdir)/../mpz/sqrtrem.c $(H)
+sub.o: $(srcdir)/../mpz/sub.c $(H)
diff --git a/gnu/lib/libgmp/mpbsd/configure.in b/gnu/lib/libgmp/mpbsd/configure.in
new file mode 100644
index 0000000..ec22075
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/configure.in
@@ -0,0 +1,20 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=
+srctrigger=itom.c
+srcname="GNU Multi-Precision library/mpbsd"
+
+# per-host:
+
+# per-target:
+
+mpzfiles="add.c cmp.c gcd.c mul.c pow_ui.c powm.c sqrtrem.c sub.c"
+
+for fn in $mpzfiles
+ do
+ rm -f $fn
+ files="$files ../mpz/$fn"
+ links="$links $fn"
+ done
diff --git a/gnu/lib/libgmp/mpbsd/itom.c b/gnu/lib/libgmp/mpbsd/itom.c
new file mode 100644
index 0000000..719a4dc
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/itom.c
@@ -0,0 +1,54 @@
+/* itom -- BSD compatible allocate and initiate a MINT.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+MINT *
+#if __STDC__
+itom (signed short int n)
+#else
+itom (n)
+ short int n;
+#endif
+{
+ MINT *x;
+ mp_ptr xp;
+
+ x = (MINT *) (*_mp_allocate_func) (sizeof (MINT));
+ x->_mp_alloc = 1;
+ x->_mp_d = xp = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ if (n > 0)
+ {
+ x->_mp_size = 1;
+ xp[0] = n;
+ }
+ else if (n < 0)
+ {
+ x->_mp_size = -1;
+ xp[0] = -n;
+ }
+ else
+ x->_mp_size = 0;
+
+ return x;
+}
diff --git a/gnu/lib/libgmp/mpbsd/mdiv.c b/gnu/lib/libgmp/mpbsd/mdiv.c
new file mode 100644
index 0000000..103c2c3
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/mdiv.c
@@ -0,0 +1,39 @@
+/* mdiv -- BSD compatible divide producing both remainder and quotient.
+
+Copyright (C) 1991, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mdiv (const MINT *num, const MINT *den, MINT *quot, MINT *rem)
+#else
+mdiv (num, den, quot, rem)
+ const MINT *num;
+ const MINT *den;
+ MINT *quot;
+ MINT *rem;
+#endif
+
+#define COMPUTE_QUOTIENT
+#include "dmincl.c"
diff --git a/gnu/lib/libgmp/mpbsd/mfree.c b/gnu/lib/libgmp/mpbsd/mfree.c
new file mode 100644
index 0000000..ef931e3
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/mfree.c
@@ -0,0 +1,36 @@
+/* mfree -- BSD compatible mfree.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mfree (MINT *m)
+#else
+mfree (m)
+ MINT *m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_d, m->_mp_alloc * BYTES_PER_MP_LIMB);
+ (*_mp_free_func) (m, sizeof (MINT));
+}
diff --git a/gnu/lib/libgmp/mpbsd/min.c b/gnu/lib/libgmp/mpbsd/min.c
new file mode 100644
index 0000000..6edb171
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/min.c
@@ -0,0 +1,89 @@
+/* min(MINT) -- Do decimal input from standard input and store result in
+ MINT.
+
+Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+min (MINT *dest)
+#else
+min (dest)
+ MINT *dest;
+#endif
+{
+ char *str;
+ size_t alloc_size, str_size;
+ int c;
+ int negative;
+ mp_size_t dest_size;
+
+ alloc_size = 100;
+ str = (char *) (*_mp_allocate_func) (alloc_size);
+ str_size = 0;
+
+ /* Skip whitespace. */
+ do
+ c = getc (stdin);
+ while (isspace (c));
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = getc (stdin);
+ }
+
+ if (digit_value_in_base (c, 10) < 0)
+ return; /* error if no digits */
+
+ for (;;)
+ {
+ int dig;
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ dig = digit_value_in_base (c, 10);
+ if (dig < 0)
+ break;
+ str[str_size++] = dig;
+ c = getc (stdin);
+ }
+
+ ungetc (c, stdin);
+
+ dest_size = str_size / __mp_bases[10].chars_per_limb + 1;
+ if (dest->_mp_alloc < dest_size)
+ _mp_realloc (dest, dest_size);
+
+ dest_size = mpn_set_str (dest->_mp_d, (unsigned char *) str, str_size, 10);
+ dest->_mp_size = negative ? -dest_size : dest_size;
+
+ (*_mp_free_func) (str, alloc_size);
+ return;
+}
diff --git a/gnu/lib/libgmp/mpbsd/mout.c b/gnu/lib/libgmp/mpbsd/mout.c
new file mode 100644
index 0000000..a6b62be
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/mout.c
@@ -0,0 +1,96 @@
+/* mout(MINT) -- Do decimal output of MINT to standard output.
+
+Copyright (C) 1991, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mout (const MINT *x)
+#else
+mout (x)
+ const MINT *x;
+#endif
+{
+ mp_ptr xp;
+ mp_size_t x_size = x->_mp_size;
+ unsigned char *str;
+ size_t str_size;
+ char *num_to_text;
+ int i;
+ TMP_DECL (marker);
+
+ if (x_size == 0)
+ {
+ fputc ('0', stdout);
+ return;
+ }
+ if (x_size < 0)
+ {
+ fputc ('-', stdout);
+ x_size = -x_size;
+ }
+
+ TMP_MARK (marker);
+ str_size = ((size_t) (x_size * BITS_PER_MP_LIMB
+ * __mp_bases[10].chars_per_bit_exactly)) + 3;
+ str = (unsigned char *) TMP_ALLOC (str_size);
+
+ /* Move the number to convert into temporary space, since mpn_get_str
+ clobbers its argument + needs one extra high limb.... */
+ xp = (mp_ptr) TMP_ALLOC ((x_size + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (xp, x->_mp_d, x_size);
+
+ str_size = mpn_get_str (str, 10, xp, x_size);
+
+ /* mpn_get_str might make some leading zeros. Skip them. */
+ while (*str == 0)
+ {
+ str_size--;
+ str++;
+ }
+
+ /* Translate to printable chars. */
+ for (i = 0; i < str_size; i++)
+ str[i] = "0123456789"[str[i]];
+ str[str_size] = 0;
+
+ str_size = strlen (str);
+ if (str_size % 10 != 0)
+ {
+ fwrite (str, 1, str_size % 10, stdout);
+ str += str_size % 10;
+ str_size -= str_size % 10;
+ if (str_size != 0)
+ fputc (' ', stdout);
+ }
+ for (i = 0; i < str_size; i += 10)
+ {
+ fwrite (str, 1, 10, stdout);
+ str += 10;
+ if (i + 10 < str_size)
+ fputc (' ', stdout);
+ }
+ fputc ('\n', stdout);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpbsd/move.c b/gnu/lib/libgmp/mpbsd/move.c
new file mode 100644
index 0000000..8256cc7
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/move.c
@@ -0,0 +1,46 @@
+/* move -- BSD compatible assignment.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+move (const MINT *u, MINT *w)
+#else
+move (u, w)
+ const MINT *u;
+ MINT *w;
+#endif
+{
+ mp_size_t usize;
+ mp_size_t abs_usize;
+
+ usize = u->_mp_size;
+ abs_usize = ABS (usize);
+
+ if (w->_mp_alloc < abs_usize)
+ _mp_realloc (w, abs_usize);
+
+ w->_mp_size = usize;
+ MPN_COPY (w->_mp_d, u->_mp_d, abs_usize);
+}
diff --git a/gnu/lib/libgmp/mpbsd/mtox.c b/gnu/lib/libgmp/mpbsd/mtox.c
new file mode 100644
index 0000000..8baec2a
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/mtox.c
@@ -0,0 +1,81 @@
+/* mtox -- Convert OPERAND to hexadecimal and return a malloc'ed string
+ with the result of the conversion.
+
+Copyright (C) 1991, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+char *
+#if __STDC__
+mtox (const MINT *x)
+#else
+mtox (x)
+ const MINT *x;
+#endif
+{
+ mp_ptr xp;
+ mp_size_t xsize = x->_mp_size;
+ mp_size_t xsign;
+ unsigned char *str, *s;
+ size_t str_size, i;
+ int zeros;
+ char *num_to_text;
+ TMP_DECL (marker);
+
+ if (xsize == 0)
+ {
+ str = (unsigned char *) (*_mp_allocate_func) (2);
+ str[0] = '0';
+ str[1] = 0;
+ return str;
+ }
+ xsign = xsize;
+ if (xsize < 0)
+ xsize = -xsize;
+
+ TMP_MARK (marker);
+ str_size = ((size_t) (xsize * BITS_PER_MP_LIMB
+ * __mp_bases[16].chars_per_bit_exactly)) + 3;
+ str = (unsigned char *) (*_mp_allocate_func) (str_size);
+ s = str;
+
+ if (xsign < 0)
+ *s++ = '-';
+
+ /* Move the number to convert into temporary space, since mpn_get_str
+ clobbers its argument + needs one extra high limb.... */
+ xp = (mp_ptr) TMP_ALLOC ((xsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (xp, x->_mp_d, xsize);
+
+ str_size = mpn_get_str (s, 16, xp, xsize);
+
+ /* mpn_get_str might make some leading zeros. Skip them. */
+ for (zeros = 0; s[zeros] == 0; zeros++)
+ str_size--;
+
+ /* Translate to printable chars and move string down. */
+ for (i = 0; i < str_size; i++)
+ s[i] = "0123456789abcdef"[s[zeros + i]];
+ s[str_size] = 0;
+
+ return str;
+}
diff --git a/gnu/lib/libgmp/mpbsd/realloc.c b/gnu/lib/libgmp/mpbsd/realloc.c
new file mode 100644
index 0000000..64bee76
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/realloc.c
@@ -0,0 +1,44 @@
+/* _mp_realloc -- make the MINT* have NEW_SIZE digits allocated.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void *
+#if __STDC__
+_mp_realloc (MINT *m, mp_size_t new_size)
+#else
+_mp_realloc (m, new_size)
+ MINT *m;
+ mp_size_t new_size;
+#endif
+{
+ /* Never allocate zero space. */
+ if (new_size == 0)
+ new_size = 1;
+
+ m->_mp_d = (mp_ptr) (*_mp_reallocate_func) (m->_mp_d,
+ m->_mp_alloc * BYTES_PER_MP_LIMB,
+ new_size * BYTES_PER_MP_LIMB);
+ m->_mp_alloc = new_size;
+ return (void *) m->_mp_d;
+}
diff --git a/gnu/lib/libgmp/mpbsd/sdiv.c b/gnu/lib/libgmp/mpbsd/sdiv.c
new file mode 100644
index 0000000..6982e20
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/sdiv.c
@@ -0,0 +1,77 @@
+/* sdiv -- Divide a MINT by a short integer. Produce a MINT quotient
+ and a short remainder.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+sdiv (const MINT *dividend, signed short int divisor_short, MINT *quot, short *rem_ptr)
+#else
+sdiv (dividend, divisor_short, quot, rem_ptr)
+ const MINT *dividend;
+ short int divisor_short;
+ MINT *quot;
+ short *rem_ptr;
+#endif
+{
+ mp_size_t sign_dividend;
+ signed long int sign_divisor;
+ mp_size_t dividend_size, quot_size;
+ mp_ptr dividend_ptr, quot_ptr;
+ mp_limb_t divisor_limb;
+ mp_limb_t remainder_limb;
+
+ sign_dividend = dividend->_mp_size;
+ dividend_size = ABS (dividend->_mp_size);
+
+ if (dividend_size == 0)
+ {
+ quot->_mp_size = 0;
+ *rem_ptr = 0;
+ return;
+ }
+
+ sign_divisor = divisor_short;
+ divisor_limb = ABS (divisor_short);
+
+ /* No need for temporary allocation and copying even if QUOT == DIVIDEND
+ as the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->_mp_alloc < dividend_size)
+ _mp_realloc (quot, dividend_size);
+
+ quot_ptr = quot->_mp_d;
+ dividend_ptr = dividend->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr,
+ dividend_ptr, dividend_size, divisor_limb);
+
+ *rem_ptr = sign_dividend >= 0 ? remainder_limb : -remainder_limb;
+ /* The quotient is DIVIDEND_SIZE limbs, but the most significant
+ might be zero. Set QUOT_SIZE properly. */
+ quot_size = dividend_size - (quot_ptr[dividend_size - 1] == 0);
+ quot->_mp_size = (sign_divisor ^ sign_dividend) >= 0 ? quot_size : -quot_size;
+}
diff --git a/gnu/lib/libgmp/mpbsd/xtom.c b/gnu/lib/libgmp/mpbsd/xtom.c
new file mode 100644
index 0000000..5a529e8
--- /dev/null
+++ b/gnu/lib/libgmp/mpbsd/xtom.c
@@ -0,0 +1,110 @@
+/* xtom -- convert a hexadecimal string to a MINT, and return a pointer to
+ the MINT.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static int
+digit_value_in_base (c, base)
+ int c;
+ int base;
+{
+ int digit;
+
+ if (isdigit (c))
+ digit = c - '0';
+ else if (islower (c))
+ digit = c - 'a' + 10;
+ else if (isupper (c))
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ if (digit < base)
+ return digit;
+ return -1;
+}
+
+MINT *
+#if __STDC__
+xtom (const char *str)
+#else
+xtom (str)
+ const char *str;
+#endif
+{
+ size_t str_size;
+ char *s, *begs;
+ size_t i;
+ mp_size_t xsize;
+ int c;
+ int negative;
+ MINT *x = (MINT *) (*_mp_allocate_func) (sizeof (MINT));
+ TMP_DECL (marker);
+
+ /* Skip whitespace. */
+ do
+ c = *str++;
+ while (isspace (c));
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = *str++;
+ }
+
+ if (digit_value_in_base (c, 16) < 0)
+ return 0; /* error if no digits */
+
+ TMP_MARK (marker);
+ str_size = strlen (str - 1);
+ s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+ for (i = 0; i < str_size; i++)
+ {
+ if (!isspace (c))
+ {
+ int dig = digit_value_in_base (c, 16);
+ if (dig < 0)
+ {
+ TMP_FREE (marker);
+ return 0;
+ }
+ *s++ = dig;
+ }
+ c = *str++;
+ }
+
+ str_size = s - begs;
+
+ xsize = str_size / __mp_bases[16].chars_per_limb + 1;
+ x->_mp_alloc = xsize;
+ x->_mp_d = (mp_ptr) (*_mp_allocate_func) (xsize * BYTES_PER_MP_LIMB);
+
+ xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, 16);
+ x->_mp_size = negative ? -xsize : xsize;
+
+ TMP_FREE (marker);
+ return x;
+}
diff --git a/gnu/lib/libgmp/mpf/Makefile.in b/gnu/lib/libgmp/mpf/Makefile.in
new file mode 100644
index 0000000..598fa72
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/Makefile.in
@@ -0,0 +1,115 @@
+# Makefile for GNU MP/mpf functions
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+CC = gcc
+
+CFLAGS = -g -O
+AR = ar
+AR_FLAGS = rc
+SHELL = /bin/sh
+
+#### host and target specific makefile fragments come in here.
+###
+
+MPF_SRCS = init.c init2.c set.c set_ui.c set_si.c set_str.c set_d.c set_z.c \
+ iset.c iset_ui.c iset_si.c iset_str.c iset_d.c clear.c get_str.c \
+ dump.c size.c eq.c reldiff.c sqrt.c random2.c inp_str.c out_str.c \
+ add.c add_ui.c sub.c sub_ui.c ui_sub.c mul.c mul_ui.c div.c div_ui.c \
+ cmp.c cmp_ui.c cmp_si.c mul_2exp.c div_2exp.c abs.c neg.c set_q.c get_d.c \
+ set_dfl_prec.c set_prc.c set_prc_raw.c get_prc.c ui_div.c sqrt_ui.c
+MPF_OBJS = init.o init2.o set.o set_ui.o set_si.o set_str.o set_d.o set_z.o \
+ iset.o iset_ui.o iset_si.o iset_str.o iset_d.o clear.o get_str.o \
+ dump.o size.o eq.o reldiff.o sqrt.o random2.o inp_str.o out_str.o \
+ add.o add_ui.o sub.o sub_ui.o ui_sub.o mul.o mul_ui.o div.o div_ui.o \
+ cmp.o cmp_ui.o cmp_si.o mul_2exp.o div_2exp.o abs.o neg.o set_q.o get_d.o \
+ set_dfl_prec.o set_prc.o set_prc_raw.o get_prc.o ui_div.o sqrt_ui.o
+
+LATER_OBJS = inp_raw.o out_raw.o random.o pow_ui.o fac_ui.o
+
+INCLUDES = -I. -I.. -I../mpn -I$(srcdir)/..
+
+libmpf.a: Makefile $(MPF_OBJS)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ $(MPF_OBJS)
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+clean mostlyclean:
+ rm -f *.o libmpf.a
+ -cd tests; $(MAKE) $@
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+ -cd tests; $(MAKE) $@
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h ../mpn/gmp-mparam.h
+
+abs.o: $(srcdir)/abs.c $(H)
+add.o: $(srcdir)/add.c $(H)
+add_ui.o: $(srcdir)/add_ui.c $(H)
+clear.o: $(srcdir)/clear.c $(H)
+cmp.o: $(srcdir)/cmp.c $(H)
+cmp_si.o: $(srcdir)/cmp_si.c $(H)
+cmp_ui.o: $(srcdir)/cmp_ui.c $(H)
+eq.o: $(srcdir)/eq.c $(H)
+div.o: $(srcdir)/div.c $(H) $(srcdir)/../longlong.h
+div_2exp.o: $(srcdir)/div_2exp.c $(H)
+div_ui.o: $(srcdir)/div_ui.c $(H) $(srcdir)/../longlong.h
+dump.o: $(srcdir)/dump.c $(H)
+get_d.o: $(srcdir)/get_d.c $(H)
+get_prc.o: $(srcdir)/get_prc.c $(H)
+get_str.o: $(srcdir)/get_str.c $(H) $(srcdir)/../longlong.h
+init.o: $(srcdir)/init.c $(H)
+init2.o: $(srcdir)/init2.c $(H)
+inp_str.o: $(srcdir)/inp_str.c $(H)
+iset.o: $(srcdir)/iset.c $(H)
+iset_d.o: $(srcdir)/iset_d.c $(H)
+iset_si.o: $(srcdir)/iset_si.c $(H)
+iset_str.o: $(srcdir)/iset_str.c $(H)
+iset_ui.o: $(srcdir)/iset_ui.c $(H)
+mul.o: $(srcdir)/mul.c $(H)
+mul_2exp.o: $(srcdir)/mul_2exp.c $(H)
+mul_ui.o: $(srcdir)/mul_ui.c $(H)
+neg.o: $(srcdir)/neg.c $(H)
+out_str.o: $(srcdir)/out_str.c $(H)
+random2.o: $(srcdir)/random2.c $(H)
+reldiff.o: $(srcdir)/reldiff.c $(H)
+set.o: $(srcdir)/set.c $(H)
+set_d.o: $(srcdir)/set_d.c $(H)
+set_dfl_prec.o: $(srcdir)/set_dfl_prec.c $(H)
+set_prc.o: $(srcdir)/set_prc.c $(H)
+set_prc_raw.o: $(srcdir)/set_prc_raw.c $(H)
+set_q.o: $(srcdir)/set_q.c $(H)
+set_si.o: $(srcdir)/set_si.c $(H)
+set_str.o: $(srcdir)/set_str.c $(H) $(srcdir)/../longlong.h
+set_ui.o: $(srcdir)/set_ui.c $(H)
+set_z.o: $(srcdir)/set_z.c $(H)
+size.o: $(srcdir)/size.c $(H)
+sqrt.o: $(srcdir)/sqrt.c $(H)
+sqrt_ui.o: $(srcdir)/sqrt_ui.c $(H)
+sub.o: $(srcdir)/sub.c $(H)
+sub_ui.o: $(srcdir)/sub_ui.c $(H)
+ui_div.o: $(srcdir)/ui_div.c $(H) $(srcdir)/../longlong.h
+ui_sub.o: $(srcdir)/ui_sub.c $(H)
diff --git a/gnu/lib/libgmp/mpf/abs.c b/gnu/lib/libgmp/mpf/abs.c
new file mode 100644
index 0000000..029007a
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/abs.c
@@ -0,0 +1,56 @@
+/* mpf_abs -- Compute the absolute value of a float.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_abs (mpf_ptr r, mpf_srcptr u)
+#else
+mpf_abs (r, u)
+ mpf_ptr r;
+ mpf_srcptr u;
+#endif
+{
+ mp_size_t size;
+
+ size = ABS (u->_mp_size);
+ if (r != u)
+ {
+ mp_size_t prec;
+ mp_ptr rp, up;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (size > prec)
+ {
+ up += size - prec;
+ size = prec;
+ }
+
+ MPN_COPY (rp, up, size);
+ r->_mp_exp = u->_mp_exp;
+ }
+ r->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpf/add.c b/gnu/lib/libgmp/mpf/add.c
new file mode 100644
index 0000000..2db876f
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/add.c
@@ -0,0 +1,180 @@
+/* mpf_add -- Add two floats.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_add (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+#else
+mpf_add (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t uexp;
+ mp_size_t ediff;
+ mp_limb_t cy;
+ int negate;
+ TMP_DECL (marker);
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (usize == 0)
+ {
+ mpf_set (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ mpf_set (r, u);
+ return;
+ }
+
+ /* If signs of U and V are different, perform subtraction. */
+ if ((usize ^ vsize) < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_sub (r, u, &v_negated);
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Signs are now known to be the same. */
+ negate = usize < 0;
+
+ /* Make U be the operand with the largest exponent. */
+ if (u->_mp_exp < v->_mp_exp)
+ {
+ mpf_srcptr t;
+ t = u; u = v; v = t;
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ }
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec;
+ uexp = u->_mp_exp;
+ ediff = u->_mp_exp - v->_mp_exp;
+
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+#if 0
+ /* Locate the least significant non-zero limb in (the needed parts
+ of) U and V, to simplify the code below. */
+ while (up[0] == 0)
+ up++, usize--;
+ while (vp[0] == 0)
+ vp++, vsize--;
+#endif
+
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = (mp_ptr) TMP_ALLOC (prec * BYTES_PER_MP_LIMB);
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (tp != up)
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ cy = mpn_add (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size;
+ size = vsize + ediff - usize;
+ MPN_COPY (tp, vp, size);
+ cy = mpn_add (tp + size, up, usize, vp + size, usize - ediff);
+ rsize = vsize + ediff;
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = vsize + ediff - usize;
+ MPN_COPY (tp, vp, vsize);
+ MPN_ZERO (tp + vsize, ediff - usize);
+ MPN_COPY (tp + size, up, usize);
+ cy = 0;
+ rsize = size + usize;
+ }
+
+ MPN_COPY (rp, tp, rsize);
+ rp[rsize] = cy;
+ rsize += cy;
+ uexp += cy;
+ }
+
+ r->_mp_size = negate ? -rsize : rsize;
+ r->_mp_exp = uexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/add_ui.c b/gnu/lib/libgmp/mpf/add_ui.c
new file mode 100644
index 0000000..f181df4
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/add_ui.c
@@ -0,0 +1,151 @@
+/* mpf_add_ui -- Add a float and an unsigned integer.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_add_ui (mpf_ptr sum, mpf_srcptr u, unsigned long int v)
+#else
+mpf_add_ui (sum, u, v)
+ mpf_ptr sum;
+ mpf_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_srcptr up = u->_mp_d;
+ mp_ptr sump = sum->_mp_d;
+ mp_size_t usize, sumsize;
+ mp_size_t prec = sum->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+ if (usize <= 0)
+ {
+ if (usize == 0)
+ {
+ mpf_set_ui (sum, v);
+ return;
+ }
+ else
+ {
+ __mpf_struct u_negated;
+ u_negated._mp_size = -usize;
+ u_negated._mp_exp = u->_mp_exp;
+ u_negated._mp_d = u->_mp_d;
+ mpf_sub_ui (sum, &u_negated, v);
+ sum->_mp_size = -(sum->_mp_size);
+ return;
+ }
+ }
+
+ if (v == 0)
+ {
+ sum_is_u:
+ if (u != sum)
+ {
+ sumsize = MIN (usize, prec + 1);
+ MPN_COPY (sum->_mp_d, up + usize - sumsize, sumsize);
+ sum->_mp_size = sumsize;
+ sum->_mp_exp = u->_mp_exp;
+ }
+ return;
+ }
+
+ if (uexp > 0)
+ {
+ /* U >= 1. */
+ if (uexp > prec)
+ {
+ /* U >> V, V is not part of final result. */
+ goto sum_is_u;
+ }
+ else
+ {
+ /* U's "limb point" is somewhere between the first limb
+ and the PREC:th limb.
+ Both U and V are part of the final result. */
+ if (uexp > usize)
+ {
+ /* uuuuuu0000. */
+ /* + v. */
+ /* We begin with moving U to the top of SUM, to handle
+ samevar(U,SUM). */
+ MPN_COPY_DECR (sump + uexp - usize, up, usize);
+ sump[0] = v;
+ MPN_ZERO (sump + 1, uexp - usize - 1);
+#if 0 /* What is this??? */
+ if (sum == u)
+ MPN_COPY (sum->_mp_d, sump, uexp);
+#endif
+ sum->_mp_size = uexp;
+ sum->_mp_exp = uexp;
+ }
+ else
+ {
+ /* uuuuuu.uuuu */
+ /* + v. */
+ mp_limb_t cy_limb;
+ if (usize > prec)
+ {
+ /* Ignore excess limbs in U. */
+ up += usize - prec;
+ usize -= usize - prec; /* Eq. usize = prec */
+ }
+ if (sump != up)
+ MPN_COPY (sump, up, usize - uexp);
+ cy_limb = mpn_add_1 (sump + usize - uexp, up + usize - uexp,
+ uexp, (mp_limb_t) v);
+ sump[usize] = cy_limb;
+ sum->_mp_size = usize + cy_limb;
+ sum->_mp_exp = uexp + cy_limb;
+ }
+ }
+ }
+ else
+ {
+ /* U < 1, so V > U for sure. */
+ /* v. */
+ /* .0000uuuu */
+ if ((-uexp) >= prec)
+ {
+ sump[0] = v;
+ sum->_mp_size = 1;
+ sum->_mp_exp = 1;
+ }
+ else
+ {
+ if (usize + (-uexp) + 1 > prec)
+ {
+ /* Ignore excess limbs in U. */
+ up += usize + (-uexp) + 1 - prec;
+ usize -= usize + (-uexp) + 1 - prec;
+ }
+ if (sump != up)
+ MPN_COPY (sump, up, usize);
+ MPN_ZERO (sump + usize, -uexp);
+ sump[usize + (-uexp)] = v;
+ sum->_mp_size = usize + (-uexp) + 1;
+ sum->_mp_exp = 1;
+ }
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/clear.c b/gnu/lib/libgmp/mpf/clear.c
new file mode 100644
index 0000000..beaf4ee
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/clear.c
@@ -0,0 +1,35 @@
+/* mpf_clear -- de-allocate the space occupied by the dynamic digit space of
+ an integer.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_clear (mpf_ptr m)
+#else
+mpf_clear (m)
+ mpf_ptr m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_d, (m->_mp_prec + 1) * BYTES_PER_MP_LIMB);
+}
diff --git a/gnu/lib/libgmp/mpf/cmp.c b/gnu/lib/libgmp/mpf/cmp.c
new file mode 100644
index 0000000..d440e11
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/cmp.c
@@ -0,0 +1,114 @@
+/* mpf_cmp -- Compare two floats.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpf_cmp (mpf_srcptr u, mpf_srcptr v)
+#else
+mpf_cmp (u, v)
+ mpf_srcptr u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize;
+ mp_exp_t uexp, vexp;
+ int cmp;
+ int usign;
+
+ uexp = u->_mp_exp;
+ vexp = v->_mp_exp;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize ^ vsize) >= 0)
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ /* vsize >= 0 */
+ return -(vsize != 0);
+ if (vsize == 0)
+ /* usize >= 0 */
+ return usize != 0;
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return usize >= 0 ? 1 : -1;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ usign = usize >= 0 ? 1 : -1;
+
+ /* 2. Are the exponents different? */
+ if (uexp > vexp)
+ return usign;
+ if (uexp < vexp)
+ return -usign;
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+#define STRICT_MPF_NORMALIZATION 0
+#if ! STRICT_MPF_NORMALIZATION
+ /* Ignore zeroes at the low end of U and V. */
+ while (up[0] == 0)
+ {
+ up++;
+ usize--;
+ }
+ while (vp[0] == 0)
+ {
+ vp++;
+ vsize--;
+ }
+#endif
+
+ if (usize > vsize)
+ {
+ cmp = mpn_cmp (up + usize - vsize, vp, vsize);
+ if (cmp == 0)
+ return usign;
+ }
+ else if (vsize > usize)
+ {
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp == 0)
+ return -usign;
+ }
+ else
+ {
+ cmp = mpn_cmp (up, vp, usize);
+ if (cmp == 0)
+ return 0;
+ }
+ return cmp > 0 ? usign : -usign;
+}
diff --git a/gnu/lib/libgmp/mpf/cmp_si.c b/gnu/lib/libgmp/mpf/cmp_si.c
new file mode 100644
index 0000000..01f9708
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/cmp_si.c
@@ -0,0 +1,98 @@
+/* mpf_cmp_si -- Compare a float with a signed integer.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpf_cmp_si (mpf_srcptr u, long int vslimb)
+#else
+mpf_cmp_si (u, vslimb)
+ mpf_srcptr u;
+ long int vslimb;
+#endif
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_exp_t uexp;
+ int usign;
+
+ uexp = u->_mp_exp;
+ usize = u->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize < 0) == (vslimb < 0)) /* don't use xor, type size may differ */
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ /* vslimb >= 0 */
+ return -(vslimb != 0);
+ if (vslimb == 0)
+ /* usize >= 0 */
+ return usize != 0;
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return usize >= 0 ? 1 : -1;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ usign = usize >= 0 ? 1 : -1;
+
+ /* 2. Are the exponents different (V's exponent == 1)? */
+ if (uexp > 1)
+ return usign;
+ if (uexp < 1)
+ return -usign;
+
+ usize = ABS (usize);
+ vslimb = ABS (vslimb);
+
+ up = u->_mp_d;
+
+#define STRICT_MPF_NORMALIZATION 0
+#if ! STRICT_MPF_NORMALIZATION
+ /* Ignore zeroes at the low end of U and V. */
+ while (*up == 0)
+ {
+ up++;
+ usize--;
+ }
+#endif
+
+ /* 3. Now, if the number of limbs are different, we have a difference
+ since we have made sure the trailing limbs are not zero. */
+ if (usize > 1)
+ return usign;
+
+ /* 4. Compare the mantissas. */
+ if (*up > vslimb)
+ return usign;
+ else if (*up < vslimb)
+ return -usign;
+
+ /* Wow, we got zero even if we tried hard to avoid it. */
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpf/cmp_ui.c b/gnu/lib/libgmp/mpf/cmp_ui.c
new file mode 100644
index 0000000..3a4911b
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/cmp_ui.c
@@ -0,0 +1,80 @@
+/* mpf_cmp_ui -- Compare a float with an unsigned integer.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpf_cmp_ui (mpf_srcptr u, unsigned long int vlimb)
+#else
+mpf_cmp_ui (u, vlimb)
+ mpf_srcptr u;
+ unsigned long int vlimb;
+#endif
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_exp_t uexp;
+
+ uexp = u->_mp_exp;
+ usize = u->_mp_size;
+
+ /* 1. Is U negative? */
+ if (usize < 0)
+ return -1;
+ /* We rely on usize being non-negative in the code that follows. */
+
+ if (vlimb == 0)
+ return usize != 0;
+
+ /* 2. Are the exponents different (V's exponent == 1)? */
+ if (uexp > 1)
+ return 1;
+ if (uexp < 1)
+ return -1;
+
+ up = u->_mp_d;
+
+#define STRICT_MPF_NORMALIZATION 0
+#if ! STRICT_MPF_NORMALIZATION
+ /* Ignore zeroes at the low end of U. */
+ while (*up == 0)
+ {
+ up++;
+ usize--;
+ }
+#endif
+
+ /* 3. Now, if the number of limbs are different, we have a difference
+ since we have made sure the trailing limbs are not zero. */
+ if (usize > 1)
+ return 1;
+
+ /* 4. Compare the mantissas. */
+ if (*up > vlimb)
+ return 1;
+ else if (*up < vlimb)
+ return -1;
+
+ /* Wow, we got zero even if we tried hard to avoid it. */
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpf/configure.in b/gnu/lib/libgmp/mpf/configure.in
new file mode 100644
index 0000000..b6ecf8b
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/configure.in
@@ -0,0 +1,12 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=tests
+srctrigger=add_ui.c
+srcname="GNU Multi-Precision library/mpf"
+
+# per-host:
+
+# per-target:
+
diff --git a/gnu/lib/libgmp/mpf/div.c b/gnu/lib/libgmp/mpf/div.c
new file mode 100644
index 0000000..9ba6922
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/div.c
@@ -0,0 +1,144 @@
+/* mpf_div -- Divide two floats.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpf_div (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+#else
+mpf_div (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp, rtp;
+ mp_size_t usize, vsize;
+ mp_size_t rsize, tsize;
+ mp_size_t sign_quotient;
+ mp_size_t prec;
+ unsigned normalization_steps;
+ mp_limb_t q_limb;
+ mp_exp_t rexp;
+ TMP_DECL (marker);
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ sign_quotient = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ prec = r->_mp_prec;
+
+ if (vsize == 0)
+ vsize = 1 / vsize; /* divide by zero as directed */
+ if (usize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK (marker);
+ rexp = u->_mp_exp - v->_mp_exp;
+
+ rp = r->_mp_d;
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ if (vsize > prec)
+ {
+ vp += vsize - prec;
+ vsize = prec;
+ }
+
+ tsize = vsize + prec;
+ tp = (mp_ptr) TMP_ALLOC ((tsize + 1) * BYTES_PER_MP_LIMB);
+
+ if (usize > tsize)
+ {
+ up += usize - tsize;
+ usize = tsize;
+ rtp = tp;
+ }
+ else
+ {
+ MPN_ZERO (tp, tsize - usize);
+ rtp = tp + (tsize - usize);
+ }
+
+ count_leading_zeros (normalization_steps, vp[vsize - 1]);
+
+ /* Normalize the divisor and the dividend. */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tmp;
+ mp_limb_t nlimb;
+
+ /* Shift up the divisor setting the most significant bit of
+ the most significant limb. Use temporary storage not to clobber
+ the original contents of the divisor. */
+ tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tmp, vp, vsize, normalization_steps);
+ vp = tmp;
+
+ /* Shift up the dividend, possibly introducing a new most
+ significant word. Move the shifted dividend in the remainder
+ at the same time. */
+ nlimb = mpn_lshift (rtp, up, usize, normalization_steps);
+ if (nlimb != 0)
+ {
+ rtp[usize] = nlimb;
+ tsize++;
+ rexp++;
+ }
+ }
+ else
+ {
+ /* The divisor is already normalized, as required.
+ Copy it to temporary space if it overlaps with the quotient. */
+ if (vp - rp <= tsize - vsize)
+ {
+ mp_ptr tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (tmp, vp, vsize);
+ vp = (mp_srcptr) tmp;
+ }
+
+ /* Move the dividend to the remainder. */
+ MPN_COPY (rtp, up, usize);
+ }
+
+ q_limb = mpn_divmod (rp, tp, tsize, vp, vsize);
+ rsize = tsize - vsize;
+ if (q_limb)
+ {
+ rp[rsize] = q_limb;
+ rsize++;
+ rexp++;
+ }
+
+ r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
+ r->_mp_exp = rexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/div_2exp.c b/gnu/lib/libgmp/mpf/div_2exp.c
new file mode 100644
index 0000000..d729625
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/div_2exp.c
@@ -0,0 +1,79 @@
+/* mpf_div_2exp -- Divide a float by 2^n.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_div_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp)
+#else
+mpf_div_2exp (r, u, exp)
+ mpf_ptr r;
+ mpf_srcptr u;
+ unsigned long int exp;
+#endif
+{
+ mp_srcptr up;
+ mp_ptr rp = r->_mp_d;
+ mp_size_t usize;
+ mp_size_t abs_usize;
+ mp_size_t prec = r->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+
+ if (usize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ abs_usize = ABS (usize);
+ up = u->_mp_d;
+
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ }
+
+ if (exp % BITS_PER_MP_LIMB == 0)
+ {
+ if (rp != up)
+ MPN_COPY (rp, up, abs_usize);
+ r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB;
+ }
+ else
+ {
+ /* Use mpn_lshift since mpn_rshift operates upwards, and we therefore
+ would clobber part of U before using that part, when R == U. */
+ mp_limb_t cy_limb;
+ cy_limb = mpn_lshift (rp, up, abs_usize, -exp % BITS_PER_MP_LIMB);
+ rp[abs_usize] = cy_limb;
+ cy_limb = cy_limb != 0;
+
+ abs_usize += cy_limb;
+ r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB - 1 + cy_limb;
+ }
+ r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
+}
diff --git a/gnu/lib/libgmp/mpf/div_ui.c b/gnu/lib/libgmp/mpf/div_ui.c
new file mode 100644
index 0000000..050a6f0
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/div_ui.c
@@ -0,0 +1,91 @@
+/* mpf_div_ui -- Divide a float with an unsigned integer.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpf_div_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
+#else
+mpf_div_ui (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_srcptr up;
+ mp_ptr rp, tp, rtp;
+ mp_size_t usize;
+ mp_size_t rsize, tsize;
+ mp_size_t sign_quotient;
+ mp_size_t prec;
+ mp_limb_t q_limb;
+ mp_exp_t rexp;
+ TMP_DECL (marker);
+
+ usize = u->_mp_size;
+ sign_quotient = usize;
+ usize = ABS (usize);
+ prec = r->_mp_prec;
+
+ if (v == 0)
+ v = 1 / v; /* divide by zero as directed */
+ if (usize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ tsize = 1 + prec;
+ tp = (mp_ptr) TMP_ALLOC ((tsize + 1) * BYTES_PER_MP_LIMB);
+
+ if (usize > tsize)
+ {
+ up += usize - tsize;
+ usize = tsize;
+ rtp = tp;
+ }
+ else
+ {
+ MPN_ZERO (tp, tsize - usize);
+ rtp = tp + (tsize - usize);
+ }
+
+ /* Move the dividend to the remainder. */
+ MPN_COPY (rtp, up, usize);
+
+ mpn_divmod_1 (rp, tp, tsize, (mp_limb_t) v);
+ q_limb = rp[tsize - 1];
+
+ rsize = tsize - (q_limb == 0);
+ rexp = u->_mp_exp - (q_limb == 0);
+ r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
+ r->_mp_exp = rexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/dump.c b/gnu/lib/libgmp/mpf/dump.c
new file mode 100644
index 0000000..46d5c05
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/dump.c
@@ -0,0 +1,43 @@
+/* mpf_dump -- Dump a float to stdout.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_dump (mpf_srcptr u)
+#else
+mpf_dump (u)
+ mpf_srcptr u;
+#endif
+{
+ mp_exp_t exp;
+ char *str;
+
+ str = mpf_get_str (0, &exp, 10, 0, u);
+ if (str[0] == '-')
+ printf ("-0.%se%ld\n", str + 1, exp);
+ else
+ printf ("0.%se%ld\n", str, exp);
+ (*_mp_free_func) (str, 0);/* ??? broken alloc interface, pass what size ??? */
+}
diff --git a/gnu/lib/libgmp/mpf/eq.c b/gnu/lib/libgmp/mpf/eq.c
new file mode 100644
index 0000000..e6630ad
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/eq.c
@@ -0,0 +1,121 @@
+/* mpf_eq -- Compare two floats up to a specified bit #.
+
+Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpf_eq (mpf_srcptr u, mpf_srcptr v, unsigned long int n_bits)
+#else
+mpf_eq (u, v, n_bits)
+ mpf_srcptr u;
+ mpf_srcptr v;
+ unsigned long int n_bits;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize, size, i;
+ mp_exp_t uexp, vexp;
+ int usign;
+
+ uexp = u->_mp_exp;
+ vexp = v->_mp_exp;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* 1. Are the signs different? */
+ if ((usize ^ vsize) >= 0)
+ {
+ /* U and V are both non-negative or both negative. */
+ if (usize == 0)
+ return vsize == 0;
+ if (vsize == 0)
+ return 0;
+
+ /* Fall out. */
+ }
+ else
+ {
+ /* Either U or V is negative, but not both. */
+ return 0;
+ }
+
+ /* U and V have the same sign and are both non-zero. */
+
+ usign = usize >= 0 ? 1 : -1;
+
+ /* 2. Are the exponents different? */
+ if (uexp > vexp)
+ return 0; /* ??? handle (uexp = vexp + 1) */
+ if (vexp > uexp)
+ return 0; /* ??? handle (vexp = uexp + 1) */
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ /* Ignore zeroes at the low end of U and V. */
+ while (up[0] == 0)
+ {
+ up++;
+ usize--;
+ }
+ while (vp[0] == 0)
+ {
+ vp++;
+ vsize--;
+ }
+
+ if (usize > vsize)
+ {
+ if (vsize * BITS_PER_MP_LIMB < n_bits)
+ return 0; /* surely too different */
+ size = vsize;
+ }
+ else if (vsize > usize)
+ {
+ if (usize * BITS_PER_MP_LIMB < n_bits)
+ return 0; /* surely too different */
+ size = usize;
+ }
+ else
+ {
+ size = usize;
+ }
+
+ if (size > (n_bits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB)
+ size = (n_bits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
+
+ up += usize - size;
+ vp += vsize - size;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ if (up[i] != vp[i])
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/gnu/lib/libgmp/mpf/get_d.c b/gnu/lib/libgmp/mpf/get_d.c
new file mode 100644
index 0000000..a10b366
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/get_d.c
@@ -0,0 +1,54 @@
+/* double mpf_get_d (mpf_t src) -- Return the double approximation to SRC.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+double
+#if __STDC__
+mpf_get_d (mpf_srcptr src)
+#else
+mpf_get_d (src)
+ mpf_srcptr src;
+#endif
+{
+ double res;
+ mp_size_t size, i, n_limbs_to_use;
+ int negative;
+ mp_ptr qp;
+
+ size = SIZ(src);
+ if (size == 0)
+ return 0.0;
+
+ negative = size < 0;
+ size = ABS (size);
+ qp = PTR(src);
+
+ res = qp[size - 1];
+ n_limbs_to_use = MIN (LIMBS_PER_DOUBLE, size);
+ for (i = 2; i <= n_limbs_to_use; i++)
+ res = res * MP_BASE_AS_DOUBLE + qp[size - i];
+
+ res = __gmp_scale2 (res, (EXP(src) - n_limbs_to_use) * BITS_PER_MP_LIMB);
+
+ return negative ? -res : res;
+}
diff --git a/gnu/lib/libgmp/mpf/get_prc.c b/gnu/lib/libgmp/mpf/get_prc.c
new file mode 100644
index 0000000..7f7e41f
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/get_prc.c
@@ -0,0 +1,34 @@
+/* mpf_get_prec(x) -- Return the precision in bits of x.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpf_get_prec (mpf_srcptr x)
+#else
+mpf_get_prec (x)
+ mpf_srcptr x;
+#endif
+{
+ return (unsigned long int) x->_mp_prec * BITS_PER_MP_LIMB - BITS_PER_MP_LIMB;
+}
diff --git a/gnu/lib/libgmp/mpf/get_str.c b/gnu/lib/libgmp/mpf/get_str.c
new file mode 100644
index 0000000..bfee18d
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/get_str.c
@@ -0,0 +1,500 @@
+/* mpf_get_str (digit_ptr, exp, base, n_digits, a) -- Convert the floating
+ point number A to a base BASE number and store N_DIGITS raw digits at
+ DIGIT_PTR, and the base BASE exponent in the word pointed to by EXP. For
+ example, the number 3.1416 would be returned as "31416" in DIGIT_PTR and
+ 1 in EXP.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/*
+ New algorithm for converting fractions (951019):
+ 0. Call the fraction to convert F.
+ 1. Compute [exp * log(2^BITS_PER_MP_LIMB)/log(B)], i.e.,
+ [exp * BITS_PER_MP_LIMB * __mp_bases[B].chars_per_bit_exactly]. Exp is
+ the number of limbs between the limb point and the most significant
+ non-zero limb. Call this result n.
+ 2. Compute B^n.
+ 3. F*B^n will now be just below 1, which can be converted easily. (Just
+ multiply by B repeatedly, and see the digits fall out as integers.)
+ We should interrupt the conversion process of F*B^n as soon as the number
+ of digits requested have been generated.
+
+ New algorithm for converting integers (951019):
+ 0. Call the integer to convert I.
+ 1. Compute [exp * log(2^BITS_PER_MP_LIMB)/log(B)], i.e.,
+ [exp BITS_PER_MP_LIMB * __mp_bases[B].chars_per_bit_exactly]. Exp is
+ the number of limbs between the limb point and the least significant
+ non-zero limb. Call this result n.
+ 2. Compute B^n.
+ 3. I/B^n can be converted easily. (Just divide by B repeatedly. In GMP,
+ this is best done by calling mpn_get_str.)
+ Note that converting I/B^n could yield more digits than requested. For
+ efficiency, the variable n above should be set larger in such cases, to
+ kill all undesired digits in the division in step 3.
+*/
+
+char *
+#if __STDC__
+mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcptr u)
+#else
+mpf_get_str (digit_ptr, exp, base, n_digits, u)
+ char *digit_ptr;
+ mp_exp_t *exp;
+ int base;
+ size_t n_digits;
+ mpf_srcptr u;
+#endif
+{
+ mp_size_t usize;
+ mp_exp_t uexp;
+ unsigned char *str;
+ size_t str_size;
+ char *num_to_text;
+ long i; /* should be size_t */
+ mp_ptr rp;
+ mp_limb_t big_base;
+ size_t digits_computed_so_far;
+ int dig_per_u;
+ mp_srcptr up;
+ unsigned char *tstr;
+ mp_exp_t exp_in_base;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ usize = u->_mp_size;
+ uexp = u->_mp_exp;
+
+ if (base >= 0)
+ {
+ if (base == 0)
+ base = 10;
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ }
+ else
+ {
+ base = -base;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ /* Don't compute more digits than U can accurately represent.
+ Also, if 0 digits were requested, give *exactly* as many digits
+ as can be accurately represented. */
+ {
+ size_t max_digits = (((u->_mp_prec - 1) * BITS_PER_MP_LIMB)
+ * __mp_bases[base].chars_per_bit_exactly);
+ if (n_digits == 0 || n_digits > max_digits)
+ n_digits = max_digits;
+ }
+
+ if (digit_ptr == 0)
+ {
+ /* We didn't get a string from the user. Allocate one (and return
+ a pointer to it) with space for `-' and terminating null. */
+ digit_ptr = (char *) (*_mp_allocate_func) (n_digits + 2);
+ }
+
+ if (usize == 0)
+ {
+ *exp = 0;
+ *digit_ptr = 0;
+ return digit_ptr;
+ }
+
+ str = (unsigned char *) digit_ptr;
+
+ /* Allocate temporary digit space. We can't put digits directly in the user
+ area, since we almost always generate more digits than requested. */
+ tstr = (unsigned char *) TMP_ALLOC (n_digits + 3 * BITS_PER_MP_LIMB);
+
+ if (usize < 0)
+ {
+ *digit_ptr = '-';
+ str++;
+ usize = -usize;
+ }
+
+ digits_computed_so_far = 0;
+
+ if (uexp > usize)
+ {
+ /* The number has just an integral part. */
+ mp_size_t rsize;
+ mp_size_t exp_in_limbs;
+ mp_size_t msize;
+ mp_ptr tp, xp, mp;
+ int cnt;
+ mp_limb_t cy;
+ mp_size_t start_str;
+ mp_size_t n_limbs;
+
+ n_limbs = 2 + ((mp_size_t) (n_digits / __mp_bases[base].chars_per_bit_exactly)
+ / BITS_PER_MP_LIMB);
+
+ /* Compute n such that [u/B^n] contains (somewhat) more than n_digits
+ digits. (We compute less than that only if that is an exact number,
+ i.e., exp is small enough.) */
+
+ exp_in_limbs = uexp;
+
+ if (n_limbs >= exp_in_limbs)
+ {
+ /* The number is so small that we convert the entire number. */
+ exp_in_base = 0;
+ rp = (mp_ptr) TMP_ALLOC (exp_in_limbs * BYTES_PER_MP_LIMB);
+ MPN_ZERO (rp, exp_in_limbs - usize);
+ MPN_COPY (rp + (exp_in_limbs - usize), u->_mp_d, usize);
+ rsize = exp_in_limbs;
+ }
+ else
+ {
+ exp_in_limbs -= n_limbs;
+ exp_in_base = (((exp_in_limbs * BITS_PER_MP_LIMB - 1))
+ * __mp_bases[base].chars_per_bit_exactly);
+
+ rsize = exp_in_limbs + 1;
+ rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ rp[0] = base;
+ rsize = 1;
+
+ count_leading_zeros (cnt, exp_in_base);
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ mpn_mul_n (tp, rp, rp, rsize);
+ rsize = 2 * rsize;
+ rsize -= tp[rsize - 1] == 0;
+ xp = tp; tp = rp; rp = xp;
+
+ if (((exp_in_base >> i) & 1) != 0)
+ {
+ cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
+ rp[rsize] = cy;
+ rsize += cy != 0;
+ }
+ }
+
+ mp = u->_mp_d;
+ msize = usize;
+
+ {
+ mp_ptr qp;
+ mp_limb_t qflag;
+ mp_size_t xtra;
+ if (msize < rsize)
+ {
+ mp_ptr tmp = (mp_ptr) TMP_ALLOC ((rsize+1)* BYTES_PER_MP_LIMB);
+ MPN_ZERO (tmp, rsize - msize);
+ MPN_COPY (tmp + rsize - msize, mp, msize);
+ mp = tmp;
+ msize = rsize;
+ }
+ else
+ {
+ mp_ptr tmp = (mp_ptr) TMP_ALLOC ((msize+1)* BYTES_PER_MP_LIMB);
+ MPN_COPY (tmp, mp, msize);
+ mp = tmp;
+ }
+ count_leading_zeros (cnt, rp[rsize - 1]);
+ cy = 0;
+ if (cnt != 0)
+ {
+ mpn_lshift (rp, rp, rsize, cnt);
+ cy = mpn_lshift (mp, mp, msize, cnt);
+ if (cy)
+ mp[msize++] = cy;
+ }
+
+ {
+ mp_size_t qsize = n_limbs + (cy != 0);
+ qp = (mp_ptr) TMP_ALLOC ((qsize + 1) * BYTES_PER_MP_LIMB);
+ xtra = qsize - (msize - rsize);
+ qflag = mpn_divrem (qp, xtra, mp, msize, rp, rsize);
+ qp[qsize] = qflag;
+ rsize = qsize + qflag;
+ rp = qp;
+ }
+ }
+ }
+
+ str_size = mpn_get_str (tstr, base, rp, rsize);
+
+ if (str_size > n_digits + 3 * BITS_PER_MP_LIMB)
+ abort ();
+
+ start_str = 0;
+ while (tstr[start_str] == 0)
+ start_str++;
+
+ for (i = start_str; i < str_size; i++)
+ {
+ tstr[digits_computed_so_far++] = tstr[i];
+ if (digits_computed_so_far > n_digits)
+ break;
+ }
+ exp_in_base = exp_in_base + str_size - start_str;
+ goto finish_up;
+ }
+
+ exp_in_base = 0;
+
+ if (uexp > 0)
+ {
+ /* The number has an integral part, convert that first.
+ If there is a fractional part too, it will be handled later. */
+ mp_size_t start_str;
+
+ rp = (mp_ptr) TMP_ALLOC (uexp * BYTES_PER_MP_LIMB);
+ up = u->_mp_d + usize - uexp;
+ MPN_COPY (rp, up, uexp);
+
+ str_size = mpn_get_str (tstr, base, rp, uexp);
+
+ start_str = 0;
+ while (tstr[start_str] == 0)
+ start_str++;
+
+ for (i = start_str; i < str_size; i++)
+ {
+ tstr[digits_computed_so_far++] = tstr[i];
+ if (digits_computed_so_far > n_digits)
+ {
+ exp_in_base = str_size - start_str;
+ goto finish_up;
+ }
+ }
+
+ exp_in_base = str_size - start_str;
+ /* Modify somewhat and fall out to convert fraction... */
+ usize -= uexp;
+ uexp = 0;
+ }
+
+ if (usize <= 0)
+ goto finish_up;
+
+ /* Convert the fraction. */
+ {
+ mp_size_t rsize, msize;
+ mp_ptr rp, tp, xp, mp;
+ int cnt;
+ mp_limb_t cy;
+ mp_exp_t nexp;
+
+ big_base = __mp_bases[base].big_base;
+ dig_per_u = __mp_bases[base].chars_per_limb;
+
+ /* Hack for correctly (although not efficiently) converting to bases that
+ are powers of 2. If we deem it important, we could handle powers of 2
+ by shifting and masking (just like mpn_get_str). */
+ if (big_base < 10) /* logarithm of base when power of two */
+ {
+ int logbase = big_base;
+ if (dig_per_u * logbase == BITS_PER_MP_LIMB)
+ dig_per_u--;
+ big_base = (mp_limb_t) 1 << (dig_per_u * logbase);
+ /* fall out to general code... */
+ }
+
+#if 0
+ if (0 && uexp == 0)
+ {
+ rp = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ up = u->_mp_d;
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ nexp = 0;
+ }
+ else
+ {}
+#endif
+ uexp = -uexp;
+ if (u->_mp_d[usize - 1] == 0)
+ cnt = 0;
+ else
+ count_leading_zeros (cnt, u->_mp_d[usize - 1]);
+
+ nexp = ((uexp * BITS_PER_MP_LIMB) + cnt)
+ * __mp_bases[base].chars_per_bit_exactly;
+
+ if (nexp == 0)
+ {
+ rp = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ up = u->_mp_d;
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ rsize = uexp + 2;
+ rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ rp[0] = base;
+ rsize = 1;
+
+ count_leading_zeros (cnt, nexp);
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ mpn_mul_n (tp, rp, rp, rsize);
+ rsize = 2 * rsize;
+ rsize -= tp[rsize - 1] == 0;
+ xp = tp; tp = rp; rp = xp;
+
+ if (((nexp >> i) & 1) != 0)
+ {
+ cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
+ rp[rsize] = cy;
+ rsize += cy != 0;
+ }
+ }
+
+ /* Did our multiplier (base^nexp) cancel with uexp? */
+#if 0
+ if (uexp != rsize)
+ {
+ do
+ {
+ cy = mpn_mul_1 (rp, rp, rsize, big_base);
+ nexp += dig_per_u;
+ }
+ while (cy == 0);
+ rp[rsize++] = cy;
+ }
+#endif
+ mp = u->_mp_d;
+ msize = usize;
+
+ tp = (mp_ptr) TMP_ALLOC ((rsize + msize) * BYTES_PER_MP_LIMB);
+ if (rsize > msize)
+ cy = mpn_mul (tp, rp, rsize, mp, msize);
+ else
+ cy = mpn_mul (tp, mp, msize, rp, rsize);
+ rsize += msize;
+ rsize -= cy == 0;
+ rp = tp;
+
+ /* If we already output digits (for an integral part) pad
+ leading zeros. */
+ if (digits_computed_so_far != 0)
+ for (i = 0; i < nexp; i++)
+ tstr[digits_computed_so_far++] = 0;
+ }
+
+ while (digits_computed_so_far <= n_digits)
+ {
+ /* For speed: skip trailing zeroes. */
+ if (rp[0] == 0)
+ {
+ rp++;
+ rsize--;
+ if (rsize == 0)
+ {
+ n_digits = digits_computed_so_far;
+ break;
+ }
+ }
+
+ cy = mpn_mul_1 (rp, rp, rsize, big_base);
+ if (digits_computed_so_far == 0 && cy == 0)
+ {
+ abort ();
+ nexp += dig_per_u;
+ continue;
+ }
+ /* Convert N1 from BIG_BASE to a string of digits in BASE
+ using single precision operations. */
+ {
+ unsigned char *s = tstr + digits_computed_so_far + dig_per_u;
+ for (i = dig_per_u - 1; i >= 0; i--)
+ {
+ *--s = cy % base;
+ cy /= base;
+ }
+ }
+ digits_computed_so_far += dig_per_u;
+ }
+ if (exp_in_base == 0)
+ exp_in_base = -nexp;
+ }
+
+ finish_up:
+
+ /* We can have at most one leading 0. Remove it. */
+ if (tstr[0] == 0)
+ {
+ tstr++;
+ digits_computed_so_far--;
+ exp_in_base--;
+ }
+
+ /* We should normally have computed too many digits. Round the result
+ at the point indicated by n_digits. */
+ if (digits_computed_so_far > n_digits)
+ {
+ /* Round the result. */
+ if (tstr[n_digits] * 2 >= base)
+ {
+ digits_computed_so_far = n_digits;
+ for (i = n_digits - 1; i >= 0; i--)
+ {
+ unsigned int x;
+ x = ++(tstr[i]);
+ if (x < base)
+ goto rounded_ok;
+ digits_computed_so_far--;
+ }
+ tstr[0] = 1;
+ digits_computed_so_far = 1;
+ exp_in_base++;
+ rounded_ok:;
+ }
+ }
+
+ /* We might have fewer digits than requested as a result of rounding above,
+ (i.e. 0.999999 => 1.0) or because we have a number that simply doesn't
+ need many digits in this base (i.e., 0.125 in base 10). */
+ if (n_digits > digits_computed_so_far)
+ n_digits = digits_computed_so_far;
+
+ /* Remove trailing 0. There can be many zeros. */
+ while (n_digits != 0 && tstr[n_digits - 1] == 0)
+ n_digits--;
+
+ /* Translate to ascii and null-terminate. */
+ for (i = 0; i < n_digits; i++)
+ *str++ = num_to_text[tstr[i]];
+ *str = 0;
+ *exp = exp_in_base;
+ TMP_FREE (marker);
+ return digit_ptr;
+}
+
+#if COPY_THIS_TO_OTHER_PLACES
+ /* Use this expression in lots of places in the library instead of the
+ count_leading_zeros+expression that is used currently. This expression
+ is much more accurate and will save odles of memory. */
+ rsize = ((mp_size_t) (exp_in_base / __mp_bases[base].chars_per_bit_exactly)
+ + BITS_PER_MP_LIMB) / BITS_PER_MP_LIMB;
+#endif
diff --git a/gnu/lib/libgmp/mpf/init.c b/gnu/lib/libgmp/mpf/init.c
new file mode 100644
index 0000000..5370121
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/init.c
@@ -0,0 +1,38 @@
+/* mpf_init() -- Make a new multiple precision number with value 0.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init (mpf_ptr r)
+#else
+mpf_init (r)
+ mpf_ptr r;
+#endif
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+}
diff --git a/gnu/lib/libgmp/mpf/init2.c b/gnu/lib/libgmp/mpf/init2.c
new file mode 100644
index 0000000..a3e5752
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/init2.c
@@ -0,0 +1,41 @@
+/* mpf_init2() -- Make a new multiple precision number with value 0.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init2 (mpf_ptr r, unsigned long int prec_in_bits)
+#else
+mpf_init2 (r, prec_in_bits)
+ mpf_ptr r;
+ unsigned long int prec_in_bits;
+#endif
+{
+ mp_size_t prec;
+
+ prec = (MAX (53, prec_in_bits) + 2 * BITS_PER_MP_LIMB - 1)/BITS_PER_MP_LIMB;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+}
diff --git a/gnu/lib/libgmp/mpf/inp_str.c b/gnu/lib/libgmp/mpf/inp_str.c
new file mode 100644
index 0000000..1d3cd4c
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/inp_str.c
@@ -0,0 +1,89 @@
+/* mpf_inp_str(dest_float, stream, base) -- Input a number in base
+ BASE from stdio stream STREAM and store the result in DEST_FLOAT.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpf_inp_str (mpf_ptr rop, FILE *stream, int base)
+#else
+mpf_inp_str (rop, stream, base)
+ mpf_ptr rop;
+ FILE *stream;
+ int base;
+#endif
+{
+ char *str;
+ size_t alloc_size, str_size;
+ int c;
+ size_t retval;
+ size_t nread;
+
+ if (stream == 0)
+ stream = stdin;
+
+ alloc_size = 100;
+ str = (char *) (*_mp_allocate_func) (alloc_size);
+ str_size = 0;
+ nread = 0;
+
+ /* Skip whitespace. */
+ do
+ {
+ c = getc (stream);
+ nread++;
+ }
+ while (isspace (c));
+
+ for (;;)
+ {
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ if (c == EOF || isspace (c))
+ break;
+ str[str_size++] = c;
+ c = getc (stream);
+ }
+ ungetc (c, stream);
+
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ str[str_size] = 0;
+
+ retval = mpf_set_str (rop, str, base);
+ if (retval == -1)
+ return 0; /* error */
+
+ (*_mp_free_func) (str, alloc_size);
+ return str_size + nread;
+}
diff --git a/gnu/lib/libgmp/mpf/iset.c b/gnu/lib/libgmp/mpf/iset.c
new file mode 100644
index 0000000..c2362e1
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/iset.c
@@ -0,0 +1,59 @@
+/* mpf_init_set -- Initialize a float and assign it from another float.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init_set (mpf_ptr r, mpf_srcptr s)
+#else
+mpf_init_set (r, s)
+ mpf_ptr r;
+ mpf_srcptr s;
+#endif
+{
+ mp_ptr rp, sp;
+ mp_size_t ssize, size;
+ mp_size_t prec;
+
+ prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+
+ prec++; /* lie not to lose precision in assignment */
+ ssize = s->_mp_size;
+ size = ABS (ssize);
+
+ rp = r->_mp_d;
+ sp = s->_mp_d;
+
+ if (size > prec)
+ {
+ sp += size - prec;
+ size = prec;
+ }
+
+ MPN_COPY (rp, sp, size);
+
+ r->_mp_exp = s->_mp_exp;
+ r->_mp_size = ssize >= 0 ? size : -size;
+}
diff --git a/gnu/lib/libgmp/mpf/iset_d.c b/gnu/lib/libgmp/mpf/iset_d.c
new file mode 100644
index 0000000..d09e8b8
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/iset_d.c
@@ -0,0 +1,39 @@
+/* mpf_init_set_d -- Initialize a float and assign it from a double.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init_set_d (mpf_ptr r, double val)
+#else
+mpf_init_set_d (r, val)
+ mpf_ptr r;
+ double val;
+#endif
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+
+ mpf_set_d (r, val);
+}
diff --git a/gnu/lib/libgmp/mpf/iset_si.c b/gnu/lib/libgmp/mpf/iset_si.c
new file mode 100644
index 0000000..e67eef4
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/iset_si.c
@@ -0,0 +1,55 @@
+/* mpf_init_set_si() -- Initialize a float and assign it from a signed int.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init_set_si (mpf_ptr r, long int val)
+#else
+mpf_init_set_si (r, val)
+ mpf_ptr r;
+ long int val;
+#endif
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+
+ if (val > 0)
+ {
+ r->_mp_d[0] = val;
+ r->_mp_size = 1;
+ r->_mp_exp = 1;
+ }
+ else if (val < 0)
+ {
+ r->_mp_d[0] = -val;
+ r->_mp_size = -1;
+ r->_mp_exp = 1;
+ }
+ else
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/iset_str.c b/gnu/lib/libgmp/mpf/iset_str.c
new file mode 100644
index 0000000..40bfe7c
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/iset_str.c
@@ -0,0 +1,40 @@
+/* mpf_init_set_str -- Initialize a float and assign it from a string.
+
+Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpf_init_set_str (mpf_ptr r, const char *s, int base)
+#else
+mpf_init_set_str (r, s, base)
+ mpf_ptr r;
+ const char *s;
+ int base;
+#endif
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+
+ return mpf_set_str (r, s, base);
+}
diff --git a/gnu/lib/libgmp/mpf/iset_ui.c b/gnu/lib/libgmp/mpf/iset_ui.c
new file mode 100644
index 0000000..c6c24af
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/iset_ui.c
@@ -0,0 +1,40 @@
+/* mpf_init_set_ui() -- Initialize a float and assign it from an unsigned int.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_init_set_ui (mpf_ptr r, unsigned long int val)
+#else
+mpf_init_set_ui (r, val)
+ mpf_ptr r;
+ unsigned long int val;
+#endif
+{
+ mp_size_t prec = __gmp_default_fp_limb_precision;
+ r->_mp_d = (mp_ptr) (*_mp_allocate_func) ((prec + 1) * BYTES_PER_MP_LIMB);
+ r->_mp_prec = prec;
+ r->_mp_d[0] = val;
+ r->_mp_size = val != 0;
+ r->_mp_exp = val != 0;
+}
diff --git a/gnu/lib/libgmp/mpf/mul.c b/gnu/lib/libgmp/mpf/mul.c
new file mode 100644
index 0000000..8f1a2a9
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/mul.c
@@ -0,0 +1,94 @@
+/* mpf_mul -- Multiply two floats.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_mul (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+#else
+mpf_mul (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize;
+ mp_size_t sign_product;
+ mp_size_t prec = r->_mp_prec;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ sign_product = usize ^ vsize;
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+ if (vsize > prec)
+ {
+ vp += vsize - prec;
+ vsize = prec;
+ }
+
+ if (usize == 0 || vsize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0; /* ??? */
+ }
+ else
+ {
+ mp_size_t rsize;
+ mp_limb_t cy_limb;
+ mp_ptr rp, tp;
+ mp_size_t adj;
+
+ rsize = usize + vsize;
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ cy_limb = (usize >= vsize
+ ? mpn_mul (tp, up, usize, vp, vsize)
+ : mpn_mul (tp, vp, vsize, up, usize));
+
+ adj = cy_limb == 0;
+ rsize -= adj;
+ prec++;
+ if (rsize > prec)
+ {
+ tp += rsize - prec;
+ rsize = prec;
+ }
+ rp = r->_mp_d;
+ MPN_COPY (rp, tp, rsize);
+ r->_mp_exp = u->_mp_exp + v->_mp_exp - adj;
+ r->_mp_size = sign_product >= 0 ? rsize : -rsize;
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/mul_2exp.c b/gnu/lib/libgmp/mpf/mul_2exp.c
new file mode 100644
index 0000000..0ed35a0
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/mul_2exp.c
@@ -0,0 +1,89 @@
+/* mpf_mul_2exp -- Multiply a float by 2^n.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_mul_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp)
+#else
+mpf_mul_2exp (r, u, exp)
+ mpf_ptr r;
+ mpf_srcptr u;
+ unsigned long int exp;
+#endif
+{
+ mp_srcptr up;
+ mp_ptr rp = r->_mp_d;
+ mp_size_t usize;
+ mp_size_t abs_usize;
+ mp_size_t prec = r->_mp_prec;
+ mp_exp_t uexp = u->_mp_exp;
+
+ usize = u->_mp_size;
+
+ if (usize == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ abs_usize = ABS (usize);
+ up = u->_mp_d;
+
+ if (abs_usize > prec)
+ {
+ up += abs_usize - prec;
+ abs_usize = prec;
+ }
+
+ if (exp % BITS_PER_MP_LIMB == 0)
+ {
+ if (rp != up)
+ MPN_COPY (rp, up, abs_usize);
+ r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
+ r->_mp_exp = uexp + exp / BITS_PER_MP_LIMB;
+ }
+ else
+ {
+ mp_limb_t cy_limb;
+ if (r != u)
+ {
+ cy_limb = mpn_lshift (rp, up, abs_usize, exp % BITS_PER_MP_LIMB);
+ rp[abs_usize] = cy_limb;
+ cy_limb = cy_limb != 0;
+ }
+ else
+ {
+ /* Use mpn_rshift since mpn_lshift operates downwards, and we
+ therefore would clobber part of U before using that part. */
+ cy_limb = mpn_rshift (rp + 1, up, abs_usize, -exp % BITS_PER_MP_LIMB);
+ rp[0] = cy_limb;
+ cy_limb = rp[abs_usize] != 0;
+ }
+
+ abs_usize += cy_limb;
+ r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
+ r->_mp_exp = uexp + exp / BITS_PER_MP_LIMB + cy_limb;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/mul_ui.c b/gnu/lib/libgmp/mpf/mul_ui.c
new file mode 100644
index 0000000..fc87cb5
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/mul_ui.c
@@ -0,0 +1,74 @@
+/* mpf_mul_ui -- Multiply a float and an unsigned integer.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_mul_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
+#else
+mpf_mul_ui (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_size_t size;
+ mp_size_t prec = r->_mp_prec;
+ mp_limb_t cy_limb;
+ mp_ptr rp;
+
+ usize = u->_mp_size;
+ size = ABS (usize);
+
+ rp = r->_mp_d;
+ up = u->_mp_d;
+ if (size > prec)
+ {
+ up += size - prec;
+ size = prec;
+ }
+
+#if 0
+ /* Since we can do it at almost no cost, remove zero limbs at low end of
+ result. */
+ if (up[0] == 0)
+ up++, size--;
+#endif
+
+ if (size == 0 || v == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0; /* ??? */
+ }
+ else
+ {
+ cy_limb = mpn_mul_1 (rp, up, size, (mp_limb_t) v);
+ rp[size] = cy_limb;
+ cy_limb = cy_limb != 0;
+ r->_mp_exp = u->_mp_exp + cy_limb;
+ size += cy_limb;
+ r->_mp_size = usize >= 0 ? size : -size;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/neg.c b/gnu/lib/libgmp/mpf/neg.c
new file mode 100644
index 0000000..a4139fb
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/neg.c
@@ -0,0 +1,59 @@
+/* mpf_neg -- Negate a float.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_neg (mpf_ptr r, mpf_srcptr u)
+#else
+mpf_neg (r, u)
+ mpf_ptr r;
+ mpf_srcptr u;
+#endif
+{
+ mp_size_t size;
+
+ size = -u->_mp_size;
+ if (r != u)
+ {
+ mp_size_t prec;
+ mp_size_t asize;
+ mp_ptr rp, up;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ asize = ABS (size);
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ MPN_COPY (rp, up, asize);
+ r->_mp_exp = u->_mp_exp;
+ size = size >= 0 ? asize : -asize;
+ }
+ r->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpf/out_str.c b/gnu/lib/libgmp/mpf/out_str.c
new file mode 100644
index 0000000..2a7a954
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/out_str.c
@@ -0,0 +1,89 @@
+/* mpf_out_str (stream, base, n_digits, op) -- Print N_DIGITS digits from
+ the float OP to STREAM in base BASE. Return the number of characters
+ written, or 0 if an error occurred.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpf_out_str (FILE *stream, int base, size_t n_digits, mpf_srcptr op)
+#else
+mpf_out_str (stream, base, n_digits, op)
+ FILE *stream;
+ int base;
+ size_t n_digits;
+ mpf_srcptr op;
+#endif
+{
+ char *str;
+ mp_exp_t exp;
+ size_t written;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ if (base == 0)
+ base = 10;
+ if (n_digits == 0)
+ n_digits = (((op->_mp_prec - 1) * BITS_PER_MP_LIMB)
+ * __mp_bases[base].chars_per_bit_exactly);
+
+ if (stream == 0)
+ stream = stdout;
+
+ str = (char *) TMP_ALLOC (n_digits + 2); /* extra for minus sign and \0 */
+
+ mpf_get_str (str, &exp, base, n_digits, op);
+ n_digits = strlen (str);
+
+ written = 0;
+
+ /* Write sign */
+ if (str[0] == '-')
+ {
+ str++;
+ fputc ('-', stream);
+ written = 1;
+ }
+
+ fwrite ("0.", 1, 2, stream);
+ written += 2;
+
+ /* Write mantissa */
+ {
+ size_t fwret;
+ fwret = fwrite (str, 1, n_digits, stream);
+ written += fwret;
+ }
+
+ /* Write exponent */
+ {
+ int fpret;
+ fpret = fprintf (stream, (base <= 10 ? "e%ld" : "@%ld"), exp);
+ written += fpret;
+ }
+
+ TMP_FREE (marker);
+ return ferror (stream) ? 0 : written;
+}
diff --git a/gnu/lib/libgmp/mpf/random2.c b/gnu/lib/libgmp/mpf/random2.c
new file mode 100644
index 0000000..8e67b11
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/random2.c
@@ -0,0 +1,65 @@
+/* mpf_random2 -- Generate a positive random mpf_t of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Intended for testing of other MP routines.
+
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined (__hpux) || defined (alpha__) || defined (__svr4__) || defined (__SVR4)
+/* HPUX lacks random(). DEC OSF/1 1.2 random() returns a double. */
+long mrand48 ();
+static inline long
+random ()
+{
+ return mrand48 ();
+}
+#else
+long random ();
+#endif
+
+void
+#if __STDC__
+mpf_random2 (mpf_ptr x, mp_size_t size, mp_exp_t exp)
+#else
+mpf_random2 (x, size, exp)
+ mpf_ptr x;
+ mp_size_t size;
+ mp_exp_t exp;
+#endif
+{
+ mp_size_t asize;
+ mp_size_t prec = x->_mp_prec;
+
+ asize = ABS (size);
+ if (asize != 0)
+ {
+ if (asize > prec + 1)
+ asize = prec + 1;
+
+ mpn_random2 (x->_mp_d, asize);
+ }
+
+ if (exp != 0)
+ exp = random () % (2 * exp) - exp;
+ x->_mp_exp = asize == 0 ? 0 : exp;
+ x->_mp_size = size < 0 ? -asize : asize;
+}
diff --git a/gnu/lib/libgmp/mpf/reldiff.c b/gnu/lib/libgmp/mpf/reldiff.c
new file mode 100644
index 0000000..c846466
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/reldiff.c
@@ -0,0 +1,52 @@
+/* mpf_reldiff -- Generate the relative difference of two floats.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_reldiff (mpf_t rdiff, mpf_srcptr x, mpf_srcptr y)
+#else
+mpf_reldiff (rdiff, x, y)
+ mpf_t rdiff;
+ mpf_srcptr x;
+ mpf_srcptr y;
+#endif
+{
+ if (mpf_cmp_ui (x, 0) == 0)
+ {
+ mpf_set_ui (rdiff, (unsigned long int) (mpf_sgn (y) != 0));
+ }
+ else
+ {
+ mpf_t d;
+ mp_limb_t tmp_limb[2];
+
+ d->_mp_prec = 1;
+ d->_mp_d = tmp_limb;
+
+ mpf_sub (d, x, y);
+ mpf_abs (d, d);
+ mpf_div (rdiff, d, x);
+ }
+}
+
diff --git a/gnu/lib/libgmp/mpf/set.c b/gnu/lib/libgmp/mpf/set.c
new file mode 100644
index 0000000..5778b85
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set.c
@@ -0,0 +1,53 @@
+/* mpf_set -- Assign a float from another float.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set (mpf_ptr r, mpf_srcptr u)
+#else
+mpf_set (r, u)
+ mpf_ptr r;
+ mpf_srcptr u;
+#endif
+{
+ mp_ptr rp, up;
+ mp_size_t size, asize;
+ mp_size_t prec;
+
+ prec = r->_mp_prec + 1; /* lie not to lose precision in assignment */
+ size = u->_mp_size;
+ asize = ABS (size);
+ rp = r->_mp_d;
+ up = u->_mp_d;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ MPN_COPY (rp, up, asize);
+ r->_mp_exp = u->_mp_exp;
+ r->_mp_size = size >= 0 ? asize : -asize;
+}
diff --git a/gnu/lib/libgmp/mpf/set_d.c b/gnu/lib/libgmp/mpf/set_d.c
new file mode 100644
index 0000000..43eb157
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_d.c
@@ -0,0 +1,47 @@
+/* mpf_set_d -- Assign a float from a IEEE double.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_d (mpf_ptr r, double d)
+#else
+mpf_set_d (r, d)
+ mpf_ptr r;
+ double d;
+#endif
+{
+ int negative;
+
+ if (d == 0)
+ {
+ SIZ(r) = 0;
+ EXP(r) = 0;
+ return;
+ }
+ negative = d < 0;
+ d = ABS (d);
+
+ EXP(r) = __gmp_extract_double (PTR(r), d);
+ SIZ(r) = negative ? -LIMBS_PER_DOUBLE : LIMBS_PER_DOUBLE;
+}
diff --git a/gnu/lib/libgmp/mpf/set_dfl_prec.c b/gnu/lib/libgmp/mpf/set_dfl_prec.c
new file mode 100644
index 0000000..55069e4
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_dfl_prec.c
@@ -0,0 +1,40 @@
+/* mpf_set_default_prec --
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_size_t __gmp_default_fp_limb_precision
+ = (53 + 2 * BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
+
+void
+#if __STDC__
+mpf_set_default_prec (unsigned long int prec_in_bits)
+#else
+mpf_set_default_prec (prec_in_bits)
+ unsigned long int prec_in_bits;
+#endif
+{
+ mp_size_t prec;
+
+ prec = (MAX (53, prec_in_bits) + 2 * BITS_PER_MP_LIMB - 1)/BITS_PER_MP_LIMB;
+ __gmp_default_fp_limb_precision = prec;
+}
diff --git a/gnu/lib/libgmp/mpf/set_prc.c b/gnu/lib/libgmp/mpf/set_prc.c
new file mode 100644
index 0000000..10f2b06
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_prc.c
@@ -0,0 +1,57 @@
+/* mpf_set_prec(x) -- Change the precision of x.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_prec (mpf_ptr x, unsigned long int prec_in_bits)
+#else
+mpf_set_prec (x, prec_in_bits)
+ mpf_ptr x;
+ unsigned long int prec_in_bits;
+#endif
+{
+ mp_size_t prec;
+ mp_size_t size = ABS (x->_mp_size);
+
+ prec = (MAX (53, prec_in_bits) + 2 * BITS_PER_MP_LIMB - 1)/BITS_PER_MP_LIMB;
+
+ /* We want the most significant limbs, so move the limbs down if we are
+ about to truncate the value. */
+ if (size > prec + 1)
+ {
+ mp_size_t offset = size - (prec + 1);
+ mp_ptr xp = x->_mp_d;
+
+ MPN_COPY (xp, xp + offset, prec + 1);
+ }
+
+ x->_mp_d = (mp_ptr) (*_mp_reallocate_func)
+ (x->_mp_d,
+ (x->_mp_prec + 1) * BYTES_PER_MP_LIMB, (prec + 1) * BYTES_PER_MP_LIMB);
+ x->_mp_prec = prec;
+
+ /* If the precision decreased, truncate the number. */
+ if (size > prec + 1)
+ x->_mp_size = x->_mp_size >= 0 ? (prec + 1) : -(prec + 1);
+}
diff --git a/gnu/lib/libgmp/mpf/set_prc_raw.c b/gnu/lib/libgmp/mpf/set_prc_raw.c
new file mode 100644
index 0000000..f55188a
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_prc_raw.c
@@ -0,0 +1,39 @@
+/* mpf_set_prec_raw(x,bits) -- Change the precision of x without changing
+ allocation. For proper operation, the original precision need to be reset
+ sooner or later.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_prec_raw (mpf_ptr x, unsigned long int prec_in_bits)
+#else
+mpf_set_prec_raw (x, prec_in_bits)
+ mpf_ptr x;
+ unsigned long int prec_in_bits;
+#endif
+{
+ mp_size_t prec;
+ prec = (MAX (53, prec_in_bits) + 2 * BITS_PER_MP_LIMB - 1)/BITS_PER_MP_LIMB;
+ x->_mp_prec = prec;
+}
diff --git a/gnu/lib/libgmp/mpf/set_q.c b/gnu/lib/libgmp/mpf/set_q.c
new file mode 100644
index 0000000..69d81e3
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_q.c
@@ -0,0 +1,170 @@
+/* mpf_set_q (mpf_t rop, mpq_t op) -- Convert the rational op to the float rop.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Algorithm:
+ 1. Develop >= n bits of src.num / src.den, where n is the number of bits
+ in a double. This (partial) division will use all bits from the
+ denominator.
+ 2. Use the remainder to determine how to round the result.
+ 3. Assign the integral result to a temporary double.
+ 4. Scale the temporary double, and return the result.
+
+ An alternative algorithm, that would be faster:
+ 0. Let n be somewhat larger than the number of significant bits in a double.
+ 1. Extract the most significant n bits of the denominator, and an equal
+ number of bits from the numerator.
+ 2. Interpret the extracted numbers as integers, call them a and b
+ respectively, and develop n bits of the fractions ((a + 1) / b) and
+ (a / (b + 1)) using mpn_divrem.
+ 3. If the computed values are identical UP TO THE POSITION WE CARE ABOUT,
+ we are done. If they are different, repeat the algorithm from step 1,
+ but first let n = n * 2.
+ 4. If we end up using all bits from the numerator and denominator, fall
+ back to the first algorithm above.
+ 5. Just to make life harder, The computation of a + 1 and b + 1 above
+ might give carry-out... Needs special handling. It might work to
+ subtract 1 in both cases instead.
+*/
+
+void
+#if __STDC__
+mpf_set_q (mpf_t r, mpq_srcptr q)
+#else
+mpf_set_q (r, q)
+ mpf_t r;
+ mpq_srcptr q;
+#endif
+{
+ mp_ptr np, dp;
+ mp_ptr rp;
+ mp_size_t nsize, dsize;
+ mp_size_t qsize, rsize;
+ mp_size_t sign_quotient;
+ unsigned normalization_steps;
+ mp_limb_t qlimb;
+ mp_ptr qp;
+ mp_size_t prec;
+ mp_exp_t exp;
+ TMP_DECL (marker);
+
+ nsize = SIZ (&q->_mp_num);
+ dsize = SIZ (&q->_mp_den);
+
+ if (nsize == 0)
+ {
+ SIZ (r) = 0;
+ EXP (r) = 0;
+ return;
+ }
+
+ prec = PREC (r) + 1;
+
+ TMP_MARK (marker);
+
+ qp = PTR (r);
+
+ sign_quotient = nsize ^ dsize;
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+ np = PTR (&q->_mp_num);
+ dp = PTR (&q->_mp_den);
+
+ exp = nsize - dsize;
+
+ if (nsize > prec)
+ {
+ np += nsize - prec;
+ nsize = prec;
+ }
+ if (dsize > prec)
+ {
+ dp += dsize - prec;
+ dsize = prec;
+ }
+
+ rsize = MAX (nsize, dsize);
+ rp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant limb. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ if (rsize != nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ nlimb = mpn_lshift (rp + (rsize - nsize),
+ np, nsize, normalization_steps);
+ }
+ else
+ {
+ nlimb = mpn_lshift (rp, np, nsize, normalization_steps);
+ }
+ if (nlimb != 0)
+ {
+ rp[rsize] = nlimb;
+ rsize++;
+ exp++;
+ }
+ }
+ else
+ {
+ if (rsize != nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ MPN_COPY (rp + (rsize - nsize), np, nsize);
+ }
+ else
+ {
+ MPN_COPY (rp, np, rsize);
+ }
+ }
+
+ qlimb = mpn_divrem (qp, prec - 1 - (rsize - dsize), rp, rsize, dp, dsize);
+ qsize = prec - 1;
+ if (qlimb)
+ {
+ qp[qsize] = qlimb;
+ qsize++;
+ exp++;
+ }
+
+ EXP (r) = exp;
+ SIZ (r) = qsize;
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/set_si.c b/gnu/lib/libgmp/mpf/set_si.c
new file mode 100644
index 0000000..f9b4b55
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_si.c
@@ -0,0 +1,51 @@
+/* mpf_set_si() -- Assign a float from a signed int.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_si (mpf_ptr x, long int val)
+#else
+mpf_set_si (x, val)
+ mpf_ptr x;
+ long int val;
+#endif
+{
+ if (val > 0)
+ {
+ x->_mp_d[0] = val;
+ x->_mp_size = 1;
+ x->_mp_exp = 1;
+ }
+ else if (val < 0)
+ {
+ x->_mp_d[0] = -val;
+ x->_mp_size = -1;
+ x->_mp_exp = 1;
+ }
+ else
+ {
+ x->_mp_size = 0;
+ x->_mp_exp = 0;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/set_str.c b/gnu/lib/libgmp/mpf/set_str.c
new file mode 100644
index 0000000..2ab9fae
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_str.c
@@ -0,0 +1,302 @@
+/* mpf_set_str (dest, string, base) -- Convert the string STRING
+ in base BASE to a float in dest. If BASE is zero, the leading characters
+ of STRING is used to figure out the base.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <string.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+long int strtol _PROTO ((const char *, char **ptr, int));
+
+static int
+digit_value_in_base (c, base)
+ int c;
+ int base;
+{
+ int digit;
+
+ if (isdigit (c))
+ digit = c - '0';
+ else if (islower (c))
+ digit = c - 'a' + 10;
+ else if (isupper (c))
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ if (digit < base)
+ return digit;
+ return -1;
+}
+
+int
+#if __STDC__
+mpf_set_str (mpf_ptr x, const char *str, int base)
+#else
+mpf_set_str (x, str, base)
+ mpf_ptr x;
+ char *str;
+ int base;
+#endif
+{
+ size_t str_size;
+ char *s, *begs;
+ size_t i;
+ mp_size_t xsize;
+ int c;
+ int negative;
+ char *dotpos = 0;
+ int expflag;
+ int decimal_exponent_flag;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ c = *str;
+
+ /* Skip whitespace. */
+ while (isspace (c))
+ c = *++str;
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = *++str;
+ }
+
+ decimal_exponent_flag = base < 0;
+ base = ABS (base);
+
+ if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
+ return -1; /* error if no digits */
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+#if 0
+ if (c == '0')
+ {
+ base = 8;
+ c = *++str;
+ if (c == 'x' || c == 'X')
+ base = 16;
+ }
+#endif
+ }
+
+ expflag = 0;
+ str_size = strlen (str);
+ for (i = 0; i < str_size; i++)
+ {
+ c = str[i];
+ if (c == '@' || (base <= 10 && (c == 'e' || c == 'E')))
+ {
+ expflag = 1;
+ str_size = i;
+ break;
+ }
+
+ }
+
+ s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+ for (i = 0; i < str_size; i++)
+ {
+ c = *str;
+ if (!isspace (c))
+ {
+ int dig;
+
+ if (c == '.')
+ {
+ if (dotpos != 0)
+ {
+ TMP_FREE (marker);
+ return -1;
+ }
+ dotpos = s;
+ }
+ else
+ {
+ dig = digit_value_in_base (c, base);
+ if (dig < 0)
+ {
+ TMP_FREE (marker);
+ return -1;
+ }
+ *s++ = dig;
+ }
+ }
+ c = *++str;
+ }
+
+ str_size = s - begs;
+
+ xsize = str_size / __mp_bases[base].chars_per_limb + 2;
+ {
+ long exp_in_base;
+ mp_size_t rsize, msize;
+ int cnt, i;
+ mp_ptr mp, xp, tp, rp;
+ mp_limb_t cy;
+ mp_exp_t exp_in_limbs;
+ mp_size_t prec = x->_mp_prec;
+ int divflag;
+ mp_size_t xxx = 0;
+
+ mp = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB);
+ msize = mpn_set_str (mp, (unsigned char *) begs, str_size, base);
+
+ if (msize == 0)
+ {
+ x->_mp_size = 0;
+ x->_mp_exp = 0;
+ TMP_FREE (marker);
+ return 0;
+ }
+
+ if (expflag != 0)
+ exp_in_base = strtol (str + 1, (char **) 0,
+ decimal_exponent_flag ? 10 : base);
+ else
+ exp_in_base = 0;
+ if (dotpos != 0)
+ exp_in_base -= s - dotpos;
+ divflag = exp_in_base < 0;
+ exp_in_base = ABS (exp_in_base);
+
+ if (exp_in_base == 0)
+ {
+ MPN_COPY (x->_mp_d, mp, msize);
+ x->_mp_size = negative ? -msize : msize;
+ x->_mp_exp = msize;
+ TMP_FREE (marker);
+ return 0;
+ }
+
+#if 1
+ rsize = (((mp_size_t) (exp_in_base / __mp_bases[base].chars_per_bit_exactly))
+ / BITS_PER_MP_LIMB + 3);
+#else
+ count_leading_zeros (cnt, (mp_limb_t) base);
+ rsize = exp_in_base - cnt * exp_in_base / BITS_PER_MP_LIMB + 1;
+#endif
+ rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ rp[0] = base;
+ rsize = 1;
+
+ count_leading_zeros (cnt, exp_in_base);
+
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ mpn_mul_n (tp, rp, rp, rsize);
+ rsize = 2 * rsize;
+ rsize -= tp[rsize - 1] == 0;
+ xp = tp; tp = rp; rp = xp;
+
+ if (((exp_in_base >> i) & 1) != 0)
+ {
+ cy = mpn_mul_1 (rp, rp, rsize, (mp_limb_t) base);
+ rp[rsize] = cy;
+ rsize += cy != 0;
+ }
+ }
+
+ if (rsize > prec)
+ {
+ xxx += rsize - prec;
+ rp += rsize - prec;
+ rsize = prec;
+ }
+#if 0
+ if (msize > prec)
+ {
+ xxx -= msize - prec;
+ mp += msize - prec;
+ msize = prec;
+ }
+#endif
+ if (divflag)
+ {
+ mp_ptr qp;
+ mp_limb_t qflag;
+ mp_size_t xtra;
+ if (msize <= rsize)
+ {
+ /* Allocate extra limb for current divrem sematics. */
+ mp_ptr tmp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_ZERO (tmp, rsize - msize);
+ MPN_COPY (tmp + rsize - msize, mp, msize);
+ mp = tmp;
+ xxx += rsize - msize;
+ msize = rsize;
+ }
+ count_leading_zeros (cnt, rp[rsize - 1]);
+ if (cnt != 0)
+ {
+ mpn_lshift (rp, rp, rsize, cnt);
+ cy = mpn_lshift (mp, mp, msize, cnt);
+ if (cy)
+ mp[msize++] = cy;
+ }
+ qp = (mp_ptr) TMP_ALLOC ((prec + 1) * BYTES_PER_MP_LIMB);
+ xtra = prec - (msize - rsize);
+ qflag = mpn_divrem (qp, xtra, mp, msize, rp, rsize);
+ qp[prec] = qflag;
+ tp = qp;
+ rsize = prec + qflag;
+ exp_in_limbs = rsize - xtra - xxx;
+ }
+ else
+ {
+ tp = (mp_ptr) TMP_ALLOC ((rsize + msize) * BYTES_PER_MP_LIMB);
+ if (rsize > msize)
+ mpn_mul (tp, rp, rsize, mp, msize);
+ else
+ mpn_mul (tp, mp, msize, rp, rsize);
+ rsize += msize;
+ rsize -= tp[rsize - 1] == 0;
+ exp_in_limbs = rsize + xxx;
+
+ if (rsize > prec)
+ {
+ xxx = rsize - prec;
+ tp += rsize - prec;
+ rsize = prec;
+ exp_in_limbs += 0;
+ }
+ }
+
+ MPN_COPY (x->_mp_d, tp, rsize);
+ x->_mp_size = negative ? -rsize : rsize;
+ x->_mp_exp = exp_in_limbs;
+ TMP_FREE (marker);
+ return 0;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/set_ui.c b/gnu/lib/libgmp/mpf/set_ui.c
new file mode 100644
index 0000000..ead0498
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_ui.c
@@ -0,0 +1,45 @@
+/* mpf_set_ui() -- Assign a float from an unsigned int.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_ui (mpf_ptr x, unsigned long int val)
+#else
+mpf_set_ui (x, val)
+ mpf_ptr x;
+ unsigned long int val;
+#endif
+{
+ if (val != 0)
+ {
+ x->_mp_d[0] = val;
+ x->_mp_size = 1;
+ x->_mp_exp = 1;
+ }
+ else
+ {
+ x->_mp_size = 0;
+ x->_mp_exp = 0;
+ }
+}
diff --git a/gnu/lib/libgmp/mpf/set_z.c b/gnu/lib/libgmp/mpf/set_z.c
new file mode 100644
index 0000000..4fff86e
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/set_z.c
@@ -0,0 +1,54 @@
+/* mpf_set_z -- Assign a float from an integer.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_set_z (mpf_ptr r, mpz_srcptr u)
+#else
+mpf_set_z (r, u)
+ mpf_ptr r;
+ mpz_srcptr u;
+#endif
+{
+ mp_ptr rp, up;
+ mp_size_t size, asize;
+ mp_size_t prec;
+
+ prec = PREC (r) + 1;
+ size = SIZ (u);
+ asize = ABS (size);
+ rp = PTR (r);
+ up = PTR (u);
+
+ EXP (r) = asize;
+
+ if (asize > prec)
+ {
+ up += asize - prec;
+ asize = prec;
+ }
+
+ MPN_COPY (rp, up, asize);
+ SIZ (r) = size >= 0 ? asize : -asize;
+}
diff --git a/gnu/lib/libgmp/mpf/size.c b/gnu/lib/libgmp/mpf/size.c
new file mode 100644
index 0000000..23a57ec
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/size.c
@@ -0,0 +1,35 @@
+/* mpf_size(x) -- return the number of limbs currently used by the
+ value of the float X.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpf_size (mpf_srcptr x)
+#else
+mpf_size (x)
+ mpf_srcptr x;
+#endif
+{
+ return ABS (x->_mp_size);
+}
diff --git a/gnu/lib/libgmp/mpf/sqrt.c b/gnu/lib/libgmp/mpf/sqrt.c
new file mode 100644
index 0000000..6d115e4
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/sqrt.c
@@ -0,0 +1,75 @@
+/* mpf_sqrt -- Compute the square root of a float.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_sqrt (mpf_ptr r, mpf_srcptr u)
+#else
+mpf_sqrt (r, u)
+ mpf_ptr r;
+ mpf_srcptr u;
+#endif
+{
+ mp_size_t usize;
+ mp_ptr up, tp;
+ mp_size_t prec;
+ mp_exp_t tsize, rexp;
+ TMP_DECL (marker);
+
+ usize = u->_mp_size;
+ if (usize <= 0)
+ {
+ usize = 1 - 1 / (usize == 0); /* Divide by zero for negative OP. */
+ r->_mp_size = usize; /* cheat flow by using usize here */
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ prec = r->_mp_prec;
+ rexp = (u->_mp_exp + 1) >> 1; /* round towards -inf */
+ tsize = 2 * prec + (u->_mp_exp & 1);
+
+ up = u->_mp_d;
+ tp = (mp_ptr) TMP_ALLOC (tsize * BYTES_PER_MP_LIMB);
+
+ if (usize > tsize)
+ {
+ up += usize - tsize;
+ usize = tsize;
+ MPN_COPY (tp, up, tsize);
+ }
+ else
+ {
+ MPN_ZERO (tp, tsize - usize);
+ MPN_COPY (tp + (tsize - usize), up, usize);
+ }
+
+ mpn_sqrtrem (r->_mp_d, NULL, tp, tsize);
+
+ r->_mp_size = (tsize + 1) / 2;
+ r->_mp_exp = rexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/sqrt_ui.c b/gnu/lib/libgmp/mpf/sqrt_ui.c
new file mode 100644
index 0000000..421aa021
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/sqrt_ui.c
@@ -0,0 +1,61 @@
+/* mpf_sqrt_ui -- Compute the square root of an unsigned integer.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_sqrt_ui (mpf_ptr r, unsigned long int u)
+#else
+mpf_sqrt_ui (r, u)
+ mpf_ptr r;
+ unsigned long int u;
+#endif
+{
+ mp_size_t rsize;
+ mp_ptr tp;
+ mp_size_t prec;
+ TMP_DECL (marker);
+
+ if (u == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ prec = r->_mp_prec;
+ rsize = 2 * prec + 1;
+
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ MPN_ZERO (tp, rsize - 1);
+ tp[rsize - 1] = u;
+
+ mpn_sqrtrem (r->_mp_d, NULL, tp, rsize);
+
+ r->_mp_size = prec + 1;
+ r->_mp_exp = 1;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/sub.c b/gnu/lib/libgmp/mpf/sub.c
new file mode 100644
index 0000000..b871982
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/sub.c
@@ -0,0 +1,402 @@
+/* mpf_sub -- Subtract two floats.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
+#else
+mpf_sub (r, u, v)
+ mpf_ptr r;
+ mpf_srcptr u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t exp;
+ mp_size_t ediff;
+ int negate;
+ TMP_DECL (marker);
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (usize == 0)
+ {
+ mpf_neg (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ mpf_set (r, u);
+ return;
+ }
+
+ /* If signs of U and V are different, perform addition. */
+ if ((usize ^ vsize) < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_add (r, u, &v_negated);
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Signs are now known to be the same. */
+ negate = usize < 0;
+
+ /* Make U be the operand with the largest exponent. */
+ if (u->_mp_exp < v->_mp_exp)
+ {
+ mpf_srcptr t;
+ t = u; u = v; v = t;
+ negate ^= 1;
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ }
+
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec + 1;
+ exp = u->_mp_exp;
+ ediff = u->_mp_exp - v->_mp_exp;
+
+ /* If ediff is 0 or 1, we might have a situation where the operands are
+ extremely close. We need to scan the operands from the most significant
+ end ignore the initial parts that are equal. */
+ if (ediff <= 1)
+ {
+ if (ediff == 0)
+ {
+ /* Skip leading limbs in U and V that are equal. */
+ if (up[usize - 1] == vp[vsize - 1])
+ {
+ /* This loop normally exits immediately. Optimize for that. */
+ do
+ {
+ usize--;
+ vsize--;
+ exp--;
+
+ if (usize == 0)
+ {
+ rsize = vsize;
+ tp = (mp_ptr) vp;
+ negate ^= 1;
+ goto normalize;
+ }
+ if (vsize == 0)
+ {
+ rsize = usize;
+ tp = (mp_ptr) up;
+ goto normalize;
+ }
+ }
+ while (up[usize - 1] == vp[vsize - 1]);
+ }
+
+ if (up[usize - 1] < vp[vsize - 1])
+ {
+ /* For simplicity, swap U and V. Note that since the loop above
+ wouldn't have exited unless up[usize - 1] and vp[vsize - 1]
+ were non-equal, this if-statement catches all cases where U
+ is smaller than V. */
+ { mp_srcptr tp = up; up = vp; vp = tp; }
+ { mp_size_t tsize = usize; usize = vsize; vsize = tsize; }
+ negate ^= 1;
+ /* negating ediff not necessary since it is 0. */
+ }
+
+ /* Check for
+ x+1 00000000 ...
+ x ffffffff ... */
+ if (up[usize - 1] != vp[vsize - 1] + 1)
+ goto general_case;
+ usize--;
+ vsize--;
+ exp--;
+ }
+ else /* ediff == 1 */
+ {
+ /* Check for
+ 1 00000000 ...
+ 0 ffffffff ... */
+
+ if (up[usize - 1] != 1 || vp[vsize - 1] != ~(mp_limb_t) 0
+ || (usize >= 2 && up[usize - 2] != 0))
+ goto general_case;
+
+ usize--;
+ exp--;
+ }
+
+ /* Skip sequences of 00000000/ffffffff */
+ while (vsize != 0 && usize != 0 && up[usize - 1] == 0
+ && vp[vsize - 1] == ~(mp_limb_t) 0)
+ {
+ usize--;
+ vsize--;
+ exp--;
+ }
+
+ if (usize == 0)
+ {
+ while (vsize != 0 && vp[vsize - 1] == ~(mp_limb_t) 0)
+ {
+ vsize--;
+ exp--;
+ }
+ }
+
+ if (usize > prec - 1)
+ {
+ up += usize - (prec - 1);
+ usize = prec - 1;
+ }
+ if (vsize > prec - 1)
+ {
+ vp += vsize - (prec - 1);
+ vsize = prec - 1;
+ }
+
+ tp = (mp_ptr) TMP_ALLOC (prec * BYTES_PER_MP_LIMB);
+ {
+ mp_limb_t cy_limb;
+ if (vsize == 0)
+ {
+ mp_size_t size, i;
+ size = usize;
+ for (i = 0; i < size; i++)
+ tp[i] = up[i];
+ tp[size] = 1;
+ rsize = size + 1;
+ exp++;
+ goto normalize;
+ }
+ if (usize == 0)
+ {
+ mp_size_t size, i;
+ size = vsize;
+ for (i = 0; i < size; i++)
+ tp[i] = ~vp[i];
+ cy_limb = 1 - mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ rsize = vsize;
+ if (cy_limb == 0)
+ {
+ tp[rsize] = 1;
+ rsize++;
+ exp++;
+ }
+ goto normalize;
+ }
+ if (usize >= vsize)
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ cy_limb = mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else /* (usize < vsize) */
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ mp_size_t size, i;
+ size = vsize - usize;
+ for (i = 0; i < size; i++)
+ tp[i] = ~vp[i];
+ cy_limb = mpn_sub_n (tp + size, up, vp + size, usize);
+ cy_limb+= mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ cy_limb-= mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ if (cy_limb == 0)
+ {
+ tp[rsize] = 1;
+ rsize++;
+ exp++;
+ }
+ goto normalize;
+ }
+ }
+
+general_case:
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = (mp_ptr) TMP_ALLOC (prec * BYTES_PER_MP_LIMB);
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (tp != up)
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* Locate the least significant non-zero limb in (the needed
+ parts of) U and V, to simplify the code below. */
+ for (;;)
+ {
+ if (vsize == 0)
+ {
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ goto done;
+ }
+ if (vp[0] != 0)
+ break;
+ vp++, vsize--;
+ }
+ for (;;)
+ {
+ if (usize == 0)
+ {
+ MPN_COPY (rp, vp, vsize);
+ rsize = vsize;
+ negate ^= 1;
+ goto done;
+ }
+ if (up[0] != 0)
+ break;
+ up++, usize--;
+ }
+
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (ediff == 0)
+ {
+ /* Have to compare the leading limbs of u and v
+ to determine whether to compute u - v or v - u. */
+ if (usize >= vsize)
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else /* (usize < vsize) */
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ mp_size_t size, i;
+ size = vsize - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i];
+ mpn_sub_n (tp + size, up, vp + size, usize);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ }
+ else
+ {
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i];
+ mpn_sub (tp + size, up, usize, vp + size, usize - ediff);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize + ediff;
+ }
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < vsize; i++)
+ tp[i] = ~vp[i];
+ for (i = vsize; i < size; i++)
+ tp[i] = ~(mp_limb_t) 0;
+ mpn_sub_1 (tp + size, up, usize, (mp_limb_t) 1);
+ rsize = size + usize;
+ }
+
+ normalize:
+ /* Full normalize. Optimize later. */
+ while (rsize != 0 && tp[rsize - 1] == 0)
+ {
+ rsize--;
+ exp--;
+ }
+ MPN_COPY (rp, tp, rsize);
+ }
+
+ done:
+ r->_mp_size = negate ? -rsize : rsize;
+ r->_mp_exp = exp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/sub_ui.c b/gnu/lib/libgmp/mpf/sub_ui.c
new file mode 100644
index 0000000..7806213
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/sub_ui.c
@@ -0,0 +1,49 @@
+/* mpf_sub_ui -- Subtract an unsigned integer from a float.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_sub_ui (mpf_ptr sum, mpf_srcptr u, unsigned long int v)
+#else
+mpf_sub_ui (sum, u, v)
+ mpf_ptr sum;
+ mpf_srcptr u;
+ unsigned long int v;
+#endif
+{
+ __mpf_struct vv;
+ mp_limb_t vl;
+
+ if (v == 0)
+ {
+ mpf_set (sum, u);
+ return;
+ }
+
+ vl = v;
+ vv._mp_size = 1;
+ vv._mp_d = &vl;
+ vv._mp_exp = 1;
+ mpf_sub (sum, u, &vv);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/Makefile.in b/gnu/lib/libgmp/mpf/tests/Makefile.in
new file mode 100644
index 0000000..e108b9e
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/Makefile.in
@@ -0,0 +1,75 @@
+# Makefile for mpf/tests for GNU MP
+
+srcdir = .
+
+CC = gcc
+
+TEST_LIBS = ../../libgmp.a
+INCLUDES = -I../../mpn -I$(srcdir)/../..
+CFLAGS = -g -O
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+TEST_SRCS = t-add.c t-sub.c t-conv.c t-sqrt.c t-muldiv.c t-dm2exp.c t-reuse.c ref.c
+TEST_OBJS = t-add.o t-sub.o t-conv.o t-sqrt.o t-muldiv.o t-dm2exp.c reuse.o
+TESTS = t-add t-sub t-conv t-sqrt t-muldiv t-dm2exp reuse
+
+check: Makefile st-add st-sub st-conv st-sqrt st-muldiv st-dm2exp st-reuse
+ @echo "The tests passed."
+
+st-add: t-add
+ ./t-add
+ touch $@
+st-sub: t-sub
+ ./t-sub
+ touch $@
+st-conv: t-conv
+ ./t-conv
+ touch $@
+st-sqrt: t-sqrt
+ ./t-sqrt
+ touch $@
+st-muldiv: t-muldiv
+ ./t-muldiv
+ touch $@
+st-dm2exp: t-dm2exp
+ ./t-dm2exp
+ touch $@
+st-reuse: reuse
+ ./reuse
+ touch $@
+
+H = $(srcdir)/../../gmp.h $(srcdir)/../../gmp-impl.h \
+ $(srcdir)/../../urandom.h ../../mpn/gmp-mparam.h
+
+t-add: t-add.o ref.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o ref.o $(TEST_LIBS) $(CFLAGS)
+t-sub: t-sub.o ref.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o ref.o $(TEST_LIBS) $(CFLAGS)
+t-conv: t-conv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-sqrt: t-sqrt.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-muldiv: t-muldiv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-dm2exp: t-dm2exp.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+reuse: reuse.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+
+t-add.o: $(srcdir)/t-add.c
+t-sub.o: $(srcdir)/t-sub.c
+t-conv.o: $(srcdir)/t-conv.c
+t-sqrt.o: $(srcdir)/t-sqrt.c
+t-muldiv.o: $(srcdir)/t-muldiv.c
+t-dm2exp.o: $(srcdir)/t-dm2exp.c
+reuse.o: $(srcdir)/reuse.c
+
+clean mostlyclean:
+ rm -f *.o st-* $(TESTS)
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
diff --git a/gnu/lib/libgmp/mpf/tests/configure.in b/gnu/lib/libgmp/mpf/tests/configure.in
new file mode 100644
index 0000000..319219c
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/configure.in
@@ -0,0 +1,11 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory. For more information, check any
+# existing configure script.
+
+srctrigger=t-add.c
+srcname="gmp/mpf/tests"
+
+# per-host:
+
+# per-target:
diff --git a/gnu/lib/libgmp/mpf/tests/ref.c b/gnu/lib/libgmp/mpf/tests/ref.c
new file mode 100644
index 0000000..b2c3e6c
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/ref.c
@@ -0,0 +1,203 @@
+/* Reference floating point routines.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if __STDC__
+void ref_mpf_add (mpf_t, const mpf_t, const mpf_t);
+void ref_mpf_sub (mpf_t, const mpf_t, const mpf_t);
+#else
+void ref_mpf_add ();
+void ref_mpf_sub ();
+#endif
+
+void
+#if __STDC__
+ref_mpf_add (mpf_t w, const mpf_t u, const mpf_t v)
+#else
+ref_mpf_add (w, u, v)
+ mpf_t w;
+ const mpf_t u;
+ const mpf_t v;
+#endif
+{
+ mp_size_t hi, lo, size;
+ mp_ptr ut, vt, wt;
+ int neg;
+ mp_exp_t exp;
+ mp_limb_t cy;
+ TMP_DECL (mark);
+
+ TMP_MARK (mark);
+
+ if (SIZ (u) == 0)
+ {
+ size = ABSIZ (v);
+ wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
+ MPN_COPY (wt, PTR (v), size);
+ exp = EXP (v);
+ neg = SIZ (v) < 0;
+ goto done;
+ }
+ if (SIZ (v) == 0)
+ {
+ size = ABSIZ (u);
+ wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
+ MPN_COPY (wt, PTR (u), size);
+ exp = EXP (u);
+ neg = SIZ (u) < 0;
+ goto done;
+ }
+ if ((SIZ (u) ^ SIZ (v)) < 0)
+ {
+ mpf_t tmp;
+ SIZ (tmp) = -SIZ (v);
+ EXP (tmp) = EXP (v);
+ PTR (tmp) = PTR (v);
+ ref_mpf_sub (w, u, tmp);
+ return;
+ }
+ neg = SIZ (u) < 0;
+
+ /* Compute the significance of the hi and lo end of the result. */
+ hi = MAX (EXP (u), EXP (v));
+ lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
+ size = hi - lo;
+ ut = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ vt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ wt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ MPN_ZERO (ut, size);
+ MPN_ZERO (vt, size);
+ {int off;
+ off = size + (EXP (u) - hi) - ABSIZ (u);
+ MPN_COPY (ut + off, PTR (u), ABSIZ (u));
+ off = size + (EXP (v) - hi) - ABSIZ (v);
+ MPN_COPY (vt + off, PTR (v), ABSIZ (v));
+ }
+
+ cy = mpn_add_n (wt, ut, vt, size);
+ wt[size] = cy;
+ size += cy;
+ exp = hi + cy;
+
+done:
+ if (size > PREC (w))
+ {
+ wt += size - PREC (w);
+ size = PREC (w);
+ }
+ MPN_COPY (PTR (w), wt, size);
+ SIZ (w) = neg == 0 ? size : -size;
+ EXP (w) = exp;
+ TMP_FREE (mark);
+}
+
+void
+#if __STDC__
+ref_mpf_sub (mpf_t w, const mpf_t u, const mpf_t v)
+#else
+ref_mpf_sub (w, u, v)
+ mpf_t w;
+ const mpf_t u;
+ const mpf_t v;
+#endif
+{
+ mp_size_t hi, lo, size;
+ mp_ptr ut, vt, wt;
+ int neg;
+ mp_exp_t exp;
+ TMP_DECL (mark);
+
+ TMP_MARK (mark);
+
+ if (SIZ (u) == 0)
+ {
+ size = ABSIZ (v);
+ wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
+ MPN_COPY (wt, PTR (v), size);
+ exp = EXP (v);
+ neg = SIZ (v) > 0;
+ goto done;
+ }
+ if (SIZ (v) == 0)
+ {
+ size = ABSIZ (u);
+ wt = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
+ MPN_COPY (wt, PTR (u), size);
+ exp = EXP (u);
+ neg = SIZ (u) < 0;
+ goto done;
+ }
+ if ((SIZ (u) ^ SIZ (v)) < 0)
+ {
+ mpf_t tmp;
+ SIZ (tmp) = -SIZ (v);
+ EXP (tmp) = EXP (v);
+ PTR (tmp) = PTR (v);
+ ref_mpf_add (w, u, tmp);
+ if (SIZ (u) < 0)
+ mpf_neg (w, w);
+ return;
+ }
+ neg = SIZ (u) < 0;
+
+ /* Compute the significance of the hi and lo end of the result. */
+ hi = MAX (EXP (u), EXP (v));
+ lo = MIN (EXP (u) - ABSIZ (u), EXP (v) - ABSIZ (v));
+ size = hi - lo;
+ ut = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ vt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ wt = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ MPN_ZERO (ut, size);
+ MPN_ZERO (vt, size);
+ {int off;
+ off = size + (EXP (u) - hi) - ABSIZ (u);
+ MPN_COPY (ut + off, PTR (u), ABSIZ (u));
+ off = size + (EXP (v) - hi) - ABSIZ (v);
+ MPN_COPY (vt + off, PTR (v), ABSIZ (v));
+ }
+
+ if (mpn_cmp (ut, vt, size) >= 0)
+ mpn_sub_n (wt, ut, vt, size);
+ else
+ {
+ mpn_sub_n (wt, vt, ut, size);
+ neg ^= 1;
+ }
+ exp = hi;
+ while (size != 0 && wt[size - 1] == 0)
+ {
+ size--;
+ exp--;
+ }
+
+done:
+ if (size > PREC (w))
+ {
+ wt += size - PREC (w);
+ size = PREC (w);
+ }
+ MPN_COPY (PTR (w), wt, size);
+ SIZ (w) = neg == 0 ? size : -size;
+ EXP (w) = exp;
+ TMP_FREE (mark);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/reuse.c b/gnu/lib/libgmp/mpf/tests/reuse.c
new file mode 100644
index 0000000..6829cc4
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/reuse.c
@@ -0,0 +1,186 @@
+/* Test that routines allow reusing a source variable as destination. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#ifndef EXPO
+#define EXPO 32
+#endif
+
+#if __STDC__
+typedef void (*dss_func) (mpf_ptr, mpf_srcptr, mpf_srcptr);
+#else
+typedef void (*dss_func) ();
+#endif
+
+dss_func dss_funcs[] =
+{
+ mpf_div, mpf_add, mpf_mul, mpf_sub,
+};
+
+char *dss_func_names[] =
+{
+ "mpf_div", "mpf_add", "mpf_mul", "mpf_sub",
+};
+
+#if __STDC__
+typedef void (*dsi_func) (mpf_ptr, mpf_srcptr, unsigned long int);
+#else
+typedef void (*dsi_func) ();
+#endif
+
+dsi_func dsi_funcs[] =
+{
+ mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui,
+};
+
+char *dsi_func_names[] =
+{
+ "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui",
+};
+
+#if __STDC__
+typedef void (*dis_func) (mpf_ptr, unsigned long int, mpf_srcptr);
+#else
+typedef void (*dis_func) ();
+#endif
+
+dis_func dis_funcs[] =
+{
+ mpf_ui_div, mpf_ui_sub,
+};
+
+char *dis_func_names[] =
+{
+ "mpf_ui_div", "mpf_ui_sub",
+};
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ int pass, reps = 100000;
+ mpf_t in1, in2, out1;
+ unsigned long int in1i, in2i;
+ mpf_t res1, res2, res3;
+ mp_size_t bprec = 100;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (in1);
+ mpf_init (in2);
+ mpf_init (out1);
+ mpf_init (res1);
+ mpf_init (res2);
+ mpf_init (res3);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ mpf_random2 (in1, urandom () % SIZE - SIZE/2, urandom () % EXPO);
+ mpf_random2 (in2, urandom () % SIZE - SIZE/2, urandom () % EXPO);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dss_funcs[i]) (res1, in1, in2);
+
+ mpf_set (out1, in1);
+ (dss_funcs[i]) (out1, out1, in2);
+ mpf_set (res2, out1);
+
+ mpf_set (out1, in2);
+ (dss_funcs[i]) (out1, in1, out1);
+ mpf_set (res3, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dss_func_names[i], res1, res2);
+ if (mpf_cmp (res1, res3) != 0)
+ dump_abort (dss_func_names[i], res1, res3);
+ }
+
+ in2i = urandom ();
+ for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (i == 0 && in2i == 0)
+ continue;
+
+ (dsi_funcs[i]) (res1, in1, in2i);
+
+ mpf_set (out1, in1);
+ (dsi_funcs[i]) (out1, out1, in2i);
+ mpf_set (res2, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dsi_func_names[i], res1, res2);
+ }
+
+ in1i = urandom ();
+ for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++)
+ {
+ /* Don't divide by 0. */
+ if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dis_funcs[i]) (res1, in1i, in2);
+
+ mpf_set (out1, in2);
+ (dis_funcs[i]) (out1, in1i, in2);
+ mpf_set (res2, out1);
+
+ if (mpf_cmp (res1, res2) != 0)
+ dump_abort (dis_func_names[i], res1, res2);
+ }
+
+ }
+
+ exit (0);
+}
+
+dump_abort (name, res1, res2)
+ char *name;
+ mpf_t res1, res2;
+{
+ printf ("failure in %s:", name);
+ oo (res1);
+ oo (res2);
+ abort ();
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
+
+#if 0
+void mpf_div_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+void mpf_mul_2exp _PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
+
+void mpf_abs _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_sqrt _PROTO ((mpf_ptr, mpf_srcptr));
+void mpf_neg _PROTO ((mpf_ptr, mpf_srcptr));
+#endif
diff --git a/gnu/lib/libgmp/mpf/tests/t-add.c b/gnu/lib/libgmp/mpf/tests/t-add.c
new file mode 100644
index 0000000..6f985bb
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-add.c
@@ -0,0 +1,117 @@
+/* Test mpf_add.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#if __STDC__
+void ref_mpf_add (mpf_t, const mpf_t, const mpf_t);
+void ref_mpf_sub (mpf_t, const mpf_t, const mpf_t);
+#else
+void ref_mpf_add ();
+void ref_mpf_sub ();
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 100000;
+ int i;
+ mpf_t u, v, w, wref;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (wref);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+
+ mpf_add (w, u, v);
+ ref_mpf_add (wref, u, v);
+
+ mpf_reldiff (rerr, w, wref);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf ("wref = "); mpf_dump (wref);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/t-conv.c b/gnu/lib/libgmp/mpf/tests/t-conv.c
new file mode 100644
index 0000000..00d461d
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-conv.c
@@ -0,0 +1,120 @@
+/* Test mpf_get_str and mpf_set_str.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 10
+#endif
+
+#ifndef EXPO
+#define EXPO 20
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpf_t x, y;
+ int reps = 20000;
+ int i;
+ mp_size_t bprec = 100;
+ mpf_t d, rerr, max_rerr, limit_rerr;
+ char *str;
+ long bexp;
+ long size, exp;
+ int base;
+ char buf[SIZE * BITS_PER_MP_LIMB + 5];
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (x);
+ mpf_init (y);
+ mpf_init (d);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % EXPO;
+ mpf_random2 (x, size, exp);
+
+ base = urandom () % 35 + 2;
+
+ str = mpf_get_str (0, &bexp, base, 0, x);
+
+ if (str[0] == '-')
+ sprintf (buf, "-0.%s@%ld", str + 1, bexp);
+ else
+ sprintf (buf, "0.%s@%ld", str, bexp);
+
+ mpf_set_str (y, buf, -base);
+ free (str);
+
+ mpf_reldiff (rerr, x, y);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf ("base = %d\n", base);
+ printf (" x = "); mpf_dump (x);
+ printf (" y = "); mpf_dump (y);
+ abort ();
+ }
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ int i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/t-dm2exp.c b/gnu/lib/libgmp/mpf/tests/t-dm2exp.c
new file mode 100644
index 0000000..a8c4e8f
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-dm2exp.c
@@ -0,0 +1,101 @@
+/* Test mpf_div, mpf_div_2exp, mpf_mul_2exp.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int reps = 500000;
+ int i;
+ mpf_t u, v, w1, w2;
+ mp_size_t bprec = 100;
+ mpf_t rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (rerr);
+ mpf_init (limit_rerr);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w1);
+ mpf_init (w2);
+
+ for (i = 0; i < reps; i++)
+ {
+ mp_size_t res_prec;
+ unsigned long int pow2;
+
+ res_prec = urandom () % (bprec + 100);
+ mpf_set_prec (w1, res_prec);
+ mpf_set_prec (w2, res_prec);
+
+ mpf_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, res_prec);
+
+ pow2 = urandom () % 0x10000;
+ mpf_set_ui (v, 1);
+ mpf_mul_2exp (v, v, pow2);
+
+ mpf_div_2exp (w1, u, pow2);
+ mpf_div (w2, u, v);
+ mpf_reldiff (rerr, w1, w2);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_div_2exp after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" w1 = "); mpf_dump (w1);
+ printf (" w2 = "); mpf_dump (w2);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/t-muldiv.c b/gnu/lib/libgmp/mpf/tests/t-muldiv.c
new file mode 100644
index 0000000..d1721e8
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-muldiv.c
@@ -0,0 +1,161 @@
+/* Test mpf_mul, mpf_div, mpf_ui_div, and mpf_div_ui.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 100000;
+ int i;
+ mpf_t u, v, w, x;
+ mp_size_t bprec = 100;
+ mpf_t rerr, limit_rerr;
+ mp_limb_t ulimb, vlimb;
+ int single_flag;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init (rerr);
+ mpf_init (limit_rerr);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (x);
+
+ for (i = 0; i < reps; i++)
+ {
+ mp_size_t res_prec;
+
+ res_prec = urandom () % (bprec + 100);
+ mpf_set_prec (w, res_prec);
+ mpf_set_prec (x, res_prec);
+
+ mpf_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, res_prec);
+
+ single_flag = 0;
+
+ if ((urandom () & 1) != 0)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+ }
+ else
+ {
+ ulimb = urandom ();
+ mpf_set_ui (u, ulimb);
+ single_flag = 1;
+ }
+
+ if ((urandom () & 1) != 0)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+ }
+ else
+ {
+ vlimb = urandom ();
+ mpf_set_ui (v, vlimb);
+ single_flag = 2;
+ }
+
+ if (mpf_sgn (v) == 0)
+ continue;
+
+ mpf_div (w, u, v);
+ mpf_mul (x, w, v);
+ mpf_reldiff (rerr, u, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_mul or mpf_div after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+
+ if (single_flag == 2)
+ {
+ mpf_div_ui (x, u, vlimb);
+ mpf_reldiff (rerr, w, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_div_ui after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+
+ if (single_flag == 1)
+ {
+ mpf_ui_div (x, ulimb, v);
+ mpf_reldiff (rerr, w, x);
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR in mpf_div or mpf_ui_div after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf (" x = "); mpf_dump (x);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/t-sqrt.c b/gnu/lib/libgmp/mpf/tests/t-sqrt.c
new file mode 100644
index 0000000..5c72ab5
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-sqrt.c
@@ -0,0 +1,103 @@
+/* Test mpf_sqrt, mpf_mul.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 100000;
+ int i;
+ mpf_t x, y, y2;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (x);
+ mpf_init (y);
+ mpf_init (y2);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (x, size, exp);
+
+ mpf_sqrt (y, x);
+ mpf_mul (y2, y, y);
+
+ mpf_reldiff (rerr, x, y2);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" x = "); mpf_dump (x);
+ printf (" y = "); mpf_dump (y);
+ printf (" y2 = "); mpf_dump (y2);
+ abort ();
+ }
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/tests/t-sub.c b/gnu/lib/libgmp/mpf/tests/t-sub.c
new file mode 100644
index 0000000..6918866
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/tests/t-sub.c
@@ -0,0 +1,122 @@
+/* Test mpf_sub.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#if __STDC__
+void ref_mpf_add (mpf_t, const mpf_t, const mpf_t);
+void ref_mpf_sub (mpf_t, const mpf_t, const mpf_t);
+#else
+void ref_mpf_add ();
+void ref_mpf_sub ();
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_size_t size;
+ mp_exp_t exp;
+ int reps = 500000;
+ int i;
+ mpf_t u, v, w, wref;
+ mp_size_t bprec = 100;
+ mpf_t rerr, max_rerr, limit_rerr;
+
+ if (argc > 1)
+ {
+ reps = strtol (argv[1], 0, 0);
+ if (argc > 2)
+ bprec = strtol (argv[2], 0, 0);
+ }
+
+ mpf_set_default_prec (bprec);
+
+ mpf_init_set_ui (limit_rerr, 1);
+ mpf_div_2exp (limit_rerr, limit_rerr, bprec);
+#if VERBOSE
+ mpf_dump (limit_rerr);
+#endif
+ mpf_init (rerr);
+ mpf_init_set_ui (max_rerr, 0);
+
+ mpf_init (u);
+ mpf_init (v);
+ mpf_init (w);
+ mpf_init (wref);
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (u, size, exp);
+
+ size = urandom () % (2 * SIZE) - SIZE;
+ exp = urandom () % SIZE;
+ mpf_random2 (v, size, exp);
+
+ if ((urandom () & 1) != 0)
+ mpf_add_ui (u, v, 1);
+ else if ((urandom () & 1) != 0)
+ mpf_sub_ui (u, v, 1);
+
+ mpf_sub (w, u, v);
+ ref_mpf_sub (wref, u, v);
+
+ mpf_reldiff (rerr, w, wref);
+ if (mpf_cmp (rerr, max_rerr) > 0)
+ {
+ mpf_set (max_rerr, rerr);
+#if VERBOSE
+ mpf_dump (max_rerr);
+#endif
+ if (mpf_cmp (rerr, limit_rerr) > 0)
+ {
+ printf ("ERROR after %d tests\n", i);
+ printf (" u = "); mpf_dump (u);
+ printf (" v = "); mpf_dump (v);
+ printf ("wref = "); mpf_dump (wref);
+ printf (" w = "); mpf_dump (w);
+ abort ();
+ }
+ }
+ }
+
+ exit (0);
+}
+
+oo (x)
+ mpf_t x;
+{
+ mp_size_t i;
+ printf (" exp = %ld\n", x->_mp_exp);
+ printf ("size = %d\n", x->_mp_size);
+ for (i = ABS (x->_mp_size) - 1; i >= 0; i--)
+ printf ("%08lX ", x->_mp_d[i]);
+ printf ("\n");
+ mpf_dump (x);
+}
diff --git a/gnu/lib/libgmp/mpf/ui_div.c b/gnu/lib/libgmp/mpf/ui_div.c
new file mode 100644
index 0000000..a49a952
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/ui_div.c
@@ -0,0 +1,131 @@
+/* mpf_ui_div -- Divide an unsigned integer with a float.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpf_ui_div (mpf_ptr r, unsigned long int u, mpf_srcptr v)
+#else
+mpf_ui_div (r, u, v)
+ mpf_ptr r;
+ unsigned long int u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr vp;
+ mp_ptr rp, tp;
+ mp_size_t vsize;
+ mp_size_t rsize, tsize;
+ mp_size_t sign_quotient;
+ mp_size_t prec;
+ unsigned normalization_steps;
+ mp_limb_t q_limb;
+ mp_exp_t rexp;
+ TMP_DECL (marker);
+
+ vsize = v->_mp_size;
+ sign_quotient = vsize;
+ vsize = ABS (vsize);
+ prec = r->_mp_prec;
+
+ if (vsize == 0)
+ vsize = 1 / vsize; /* divide by zero as directed */
+ if (u == 0)
+ {
+ r->_mp_size = 0;
+ r->_mp_exp = 0;
+ return;
+ }
+
+ TMP_MARK (marker);
+ rexp = 1 - v->_mp_exp;
+
+ rp = r->_mp_d;
+ vp = v->_mp_d;
+
+ if (vsize > prec)
+ {
+ vp += vsize - prec;
+ vsize = prec;
+ }
+
+ tsize = vsize + prec;
+ tp = (mp_ptr) TMP_ALLOC ((tsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_ZERO (tp, tsize);
+
+ count_leading_zeros (normalization_steps, vp[vsize - 1]);
+
+ /* Normalize the divisor and the dividend. */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tmp;
+ mp_limb_t dividend_high, dividend_low;
+
+ /* Shift up the divisor setting the most significant bit of
+ the most significant limb. Use temporary storage not to clobber
+ the original contents of the divisor. */
+ tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tmp, vp, vsize, normalization_steps);
+ vp = tmp;
+
+ /* Shift up the dividend, possibly introducing a new most
+ significant word. */
+ dividend_high = (mp_limb_t) u >> (BITS_PER_MP_LIMB - normalization_steps);
+ dividend_low = (mp_limb_t) u << normalization_steps;
+
+ tp[tsize - 1] = dividend_low;
+ if (dividend_high != 0)
+ {
+ tp[tsize] = dividend_high;
+ tsize++;
+ rexp++;
+ }
+ }
+ else
+ {
+ /* The divisor is already normalized, as required.
+ Copy it to temporary space if it overlaps with the quotient. */
+ if (vp - rp <= tsize - vsize)
+ {
+ mp_ptr tmp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (tmp, vp, vsize);
+ vp = (mp_srcptr) tmp;
+ }
+
+ tp[tsize - 1] = u;
+ }
+
+ q_limb = mpn_divmod (rp, tp, tsize, vp, vsize);
+ rsize = tsize - vsize;
+ if (q_limb)
+ {
+ rp[rsize] = q_limb;
+ rsize++;
+ rexp++;
+ }
+
+ r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;
+ r->_mp_exp = rexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpf/ui_sub.c b/gnu/lib/libgmp/mpf/ui_sub.c
new file mode 100644
index 0000000..acb9210
--- /dev/null
+++ b/gnu/lib/libgmp/mpf/ui_sub.c
@@ -0,0 +1,334 @@
+/* mpf_ui_sub -- Subtract a float from an unsigned long int.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpf_ui_sub (mpf_ptr r, unsigned long int u, mpf_srcptr v)
+#else
+mpf_ui_sub (r, u, v)
+ mpf_ptr r;
+ unsigned long int u;
+ mpf_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_ptr rp, tp;
+ mp_size_t usize, vsize, rsize;
+ mp_size_t prec;
+ mp_exp_t uexp;
+ mp_size_t ediff;
+ int negate;
+ mp_limb_t ulimb;
+ TMP_DECL (marker);
+
+ vsize = v->_mp_size;
+
+ /* Handle special cases that don't work in generic code below. */
+ if (u == 0)
+ {
+ mpf_neg (r, v);
+ return;
+ }
+ if (vsize == 0)
+ {
+ mpf_set_ui (r, u);
+ return;
+ }
+
+ /* If signs of U and V are different, perform addition. */
+ if (vsize < 0)
+ {
+ __mpf_struct v_negated;
+ v_negated._mp_size = -vsize;
+ v_negated._mp_exp = v->_mp_exp;
+ v_negated._mp_d = v->_mp_d;
+ mpf_add_ui (r, &v_negated, u);
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Signs are now known to be the same. */
+
+ ulimb = u;
+ /* Make U be the operand with the largest exponent. */
+ if (1 < v->_mp_exp)
+ {
+ negate = 1;
+ usize = ABS (vsize);
+ vsize = 1;
+ up = v->_mp_d;
+ vp = &ulimb;
+ rp = r->_mp_d;
+ prec = r->_mp_prec + 1;
+ uexp = v->_mp_exp;
+ ediff = uexp - 1;
+ }
+ else
+ {
+ negate = 0;
+ usize = 1;
+ vsize = ABS (vsize);
+ up = &ulimb;
+ vp = v->_mp_d;
+ rp = r->_mp_d;
+ prec = r->_mp_prec;
+ uexp = 1;
+ ediff = 1 - v->_mp_exp;
+ }
+
+ /* Ignore leading limbs in U and V that are equal. Doing
+ this helps increase the precision of the result. */
+ if (ediff == 0)
+ {
+ /* This loop normally exits immediately. Optimize for that. */
+ for (;;)
+ {
+ usize--;
+ vsize--;
+ if (up[usize] != vp[vsize])
+ break;
+ uexp--;
+ if (usize == 0)
+ goto Lu0;
+ if (vsize == 0)
+ goto Lv0;
+ }
+ usize++;
+ vsize++;
+ /* Note that either operand (but not both operands) might now have
+ leading zero limbs. It matters only that U is unnormalized if
+ vsize is now zero, and vice versa. And it is only in that case
+ that we have to adjust uexp. */
+ if (vsize == 0)
+ Lv0:
+ while (usize != 0 && up[usize - 1] == 0)
+ usize--, uexp--;
+ if (usize == 0)
+ Lu0:
+ while (vsize != 0 && vp[vsize - 1] == 0)
+ vsize--, uexp--;
+ }
+
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+
+ /* If V extends beyond PREC, ignore the part that does.
+ Note that this may make vsize negative. */
+ if (vsize + ediff > prec)
+ {
+ vp += vsize + ediff - prec;
+ vsize = prec - ediff;
+ }
+
+ /* Allocate temp space for the result. Allocate
+ just vsize + ediff later??? */
+ tp = (mp_ptr) TMP_ALLOC (prec * BYTES_PER_MP_LIMB);
+
+ if (ediff >= prec)
+ {
+ /* V completely cancelled. */
+ if (tp != up)
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ }
+ else
+ {
+ /* Locate the least significant non-zero limb in (the needed
+ parts of) U and V, to simplify the code below. */
+ for (;;)
+ {
+ if (vsize == 0)
+ {
+ MPN_COPY (rp, up, usize);
+ rsize = usize;
+ goto done;
+ }
+ if (vp[0] != 0)
+ break;
+ vp++, vsize--;
+ }
+ for (;;)
+ {
+ if (usize == 0)
+ {
+ MPN_COPY (rp, vp, vsize);
+ rsize = vsize;
+ negate ^= 1;
+ goto done;
+ }
+ if (up[0] != 0)
+ break;
+ up++, usize--;
+ }
+
+ /* uuuu | uuuu | uuuu | uuuu | uuuu */
+ /* vvvvvvv | vv | vvvvv | v | vv */
+
+ if (usize > ediff)
+ {
+ /* U and V partially overlaps. */
+ if (ediff == 0)
+ {
+ /* Have to compare the leading limbs of u and v
+ to determine whether to compute u - v or v - u. */
+ if (usize > vsize)
+ {
+ /* uuuu */
+ /* vv */
+ int cmp;
+ cmp = mpn_cmp (up + usize - vsize, vp, vsize);
+ if (cmp >= 0)
+ {
+ mp_size_t size;
+ size = usize - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub_n (tp + size, up + size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* vv */ /* Swap U and V. */
+ /* uuuu */
+ mp_size_t size, i;
+ size = usize - vsize;
+ tp[0] = -up[0];
+ for (i = 1; i < size; i++)
+ tp[i] = ~up[i];
+ mpn_sub_n (tp + size, vp, up + size, vsize);
+ mpn_sub_1 (tp + size, tp + size, vsize, (mp_limb_t) 1);
+ negate ^= 1;
+ rsize = usize;
+ }
+ }
+ else if (usize < vsize)
+ {
+ /* uuuu */
+ /* vvvvvvv */
+ int cmp;
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp > 0)
+ {
+ mp_size_t size, i;
+ size = vsize - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i];
+ mpn_sub_n (tp + size, up, vp + size, usize);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize;
+ }
+ else
+ {
+ /* vvvvvvv */ /* Swap U and V. */
+ /* uuuu */
+ /* This is the only place we can get 0.0. */
+ mp_size_t size;
+ size = vsize - usize;
+ MPN_COPY (tp, vp, size);
+ mpn_sub_n (tp + size, vp + size, up, usize);
+ negate ^= 1;
+ rsize = vsize;
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvv */
+ int cmp;
+ cmp = mpn_cmp (up, vp + vsize - usize, usize);
+ if (cmp > 0)
+ {
+ mpn_sub_n (tp, up, vp, usize);
+ rsize = usize;
+ }
+ else
+ {
+ mpn_sub_n (tp, vp, up, usize);
+ negate ^= 1;
+ rsize = usize;
+ /* can give zero */
+ }
+ }
+ }
+ else
+ {
+ if (vsize + ediff <= usize)
+ {
+ /* uuuu */
+ /* v */
+ mp_size_t size;
+ size = usize - ediff - vsize;
+ MPN_COPY (tp, up, size);
+ mpn_sub (tp + size, up + size, usize - size, vp, vsize);
+ rsize = usize;
+ }
+ else
+ {
+ /* uuuu */
+ /* vvvvv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < size; i++)
+ tp[i] = ~vp[i];
+ mpn_sub (tp + size, up, usize, vp + size, usize - ediff);
+ mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ rsize = vsize + ediff;
+ }
+ }
+ }
+ else
+ {
+ /* uuuu */
+ /* vv */
+ mp_size_t size, i;
+ size = vsize + ediff - usize;
+ tp[0] = -vp[0];
+ for (i = 1; i < vsize; i++)
+ tp[i] = ~vp[i];
+ for (i = vsize; i < size; i++)
+ tp[i] = ~(mp_limb_t) 0;
+ mpn_sub_1 (tp + size, up, usize, (mp_limb_t) 1);
+ rsize = size + usize;
+ }
+
+ /* Full normalize. Optimize later. */
+ while (rsize != 0 && tp[rsize - 1] == 0)
+ {
+ rsize--;
+ uexp--;
+ }
+ MPN_COPY (rp, tp, rsize);
+ }
+
+ done:
+ r->_mp_size = negate ? -rsize : rsize;
+ r->_mp_exp = uexp;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpn/Makefile.in b/gnu/lib/libgmp/mpn/Makefile.in
new file mode 100644
index 0000000..132159b
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/Makefile.in
@@ -0,0 +1,92 @@
+# Makefile for GNU MP/mpn functions
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+MPN_OBJECTS = This gets filled in by configure.in.
+MPN_LINKS = This gets filled in by configure.in.
+CC = gcc
+CPP = $(CC) -E
+CFLAGS = -g -O
+INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/..
+AR = ar
+AR_FLAGS = rc
+SFLAGS=
+
+#### host and target specific makefile fragments come in here.
+###
+
+libmpn.a: Makefile mp_bases.o $(MPN_OBJECTS)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ mp_bases.o $(MPN_OBJECTS)
+
+.SUFFIXES: .c .s .S
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+.s.o:
+ $(CC) -c $(CFLAGS) $<
+
+.S.o:
+ $(CPP) $(SFLAGS) $(INCLUDES) $(CFLAGS) $< | grep -v '^#' >tmp-$*.s
+ $(CC) -c tmp-$*.s -o $@
+ rm -f tmp-$*.s
+
+clean mostlyclean:
+ rm -f *.o tmp-* libmpn.a
+ #-cd tests; $(MAKE) $@
+distclean maintainer-clean: clean
+ rm -f asm-syntax.h Makefile config.status $(MPN_LINKS)
+ -cd tests; $(MAKE) $@
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+
+# Maybe configure could add dependencies here..?
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h gmp-mparam.h
+L = $(srcdir)/../longlong.h
+
+mp_bases.o: $(srcdir)/mp_bases.c $(H)
+bdivmod.o: bdivmod.c $(H) $(L)
+cmp.o: cmp.c $(H)
+divmod_1.o: divmod_1.c $(H) $(L)
+divrem.o: divrem.c $(H) $(L)
+divrem_1.o: divrem_1.c $(H) $(L)
+dump.o: dump.c $(H)
+gcd.o: gcd.c $(H) $(L)
+gcd_1.o: gcd_1.c $(H) $(L)
+gcdext.o: gcdext.c $(H) $(L)
+get_str.o: get_str.c $(H) $(L)
+hamdist.o: hamdist.c $(H)
+inlines.o: inlines.c $(srcdir)/../gmp.h
+mod_1.o: mod_1.c $(H) $(L)
+mul.o: mul.c $(H)
+mul_n.o: mul_n.c $(H)
+perfsqr.o: perfsqr.c $(H) $(L)
+popcount.o: popcount.c $(H)
+pre_mod_1.o: pre_mod_1.c $(H) $(L)
+random2.o: random2.c $(H)
+scan0.o: scan0.c $(H) $(L)
+scan1.o: scan1.c $(H) $(L)
+set_str.o: set_str.c $(H)
+sqrtrem.o: sqrtrem.c $(H) $(L)
diff --git a/gnu/lib/libgmp/mpn/README b/gnu/lib/libgmp/mpn/README
new file mode 100644
index 0000000..3da559e
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/README
@@ -0,0 +1,15 @@
+This directory contains all code for the mpn layer of GMP.
+
+Most subdirectories contain machine-dependent code, written in assembly or
+C. The `generic' subdirectory contains default code, used when there is no
+machine-dependent replacement for a particular machine.
+
+There is one subdirectory for each architecture. Note that e.g., 32-bit
+sparc and 64-bit sparc cannot share any code, and are therefore considered
+completely different architecture.
+
+A particular machine will only use code from one such subdirectory, and the
+`generic' subdirectory. The architecture-specific subdirectory contains a
+hierachy of directories for various architecture variants and
+implementations; the top-most level contains code that runs correctly on all
+variants.
diff --git a/gnu/lib/libgmp/mpn/bsd.h b/gnu/lib/libgmp/mpn/bsd.h
new file mode 100644
index 0000000..8a0cbce
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/bsd.h
@@ -0,0 +1,5 @@
+#if __STDC__
+#define C_SYMBOL_NAME(name) _##name
+#else
+#define C_SYMBOL_NAME(name) _/**/name
+#endif
diff --git a/gnu/lib/libgmp/mpn/config/t-oldgas b/gnu/lib/libgmp/mpn/config/t-oldgas
new file mode 100644
index 0000000..ba02fa7
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/config/t-oldgas
@@ -0,0 +1 @@
+SFLAGS=-DBROKEN_ALIGN
diff --git a/gnu/lib/libgmp/mpn/config/t-ppc-aix b/gnu/lib/libgmp/mpn/config/t-ppc-aix
new file mode 100644
index 0000000..a31ce0d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/config/t-ppc-aix
@@ -0,0 +1 @@
+SFLAGS=-Wa,-mppc
diff --git a/gnu/lib/libgmp/mpn/config/t-pwr-aix b/gnu/lib/libgmp/mpn/config/t-pwr-aix
new file mode 100644
index 0000000..3e11d9f
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/config/t-pwr-aix
@@ -0,0 +1 @@
+SFLAGS=-Wa,-mpwr
diff --git a/gnu/lib/libgmp/mpn/configure.in b/gnu/lib/libgmp/mpn/configure.in
new file mode 100644
index 0000000..90c2626
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/configure.in
@@ -0,0 +1,178 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=
+srctrigger=powerpc32
+srcname="GNU Multi-Precision library/mpn"
+
+# per-host:
+
+# per-target:
+
+case "${target}" in
+ sparc9*-*-* | sparc64*-*-* | ultrasparc*-*-*)
+ #path="sparc64" ;; Don't use this until compilers are ready
+ path="sparc32/v8 sparc" ;;
+ sparc8*-*-* | microsparc*-*-*)
+ path="sparc32/v8 sparc" ;;
+ supersparc*-*-*)
+ path="sparc32/v8/supersparc sparc32/v8 sparc"
+ extra_functions="udiv" ;;
+ sparc*-*-*) path="sparc32"
+ if [ x$floating_point = xno ]
+ then extra_functions="udiv_nfp"
+ else extra_functions="udiv_fp"
+ fi
+ ;;
+ hppa7000*-*-*) path="hppa/hppa1_1 hppa"; extra_functions="udiv_qrnnd" ;;
+ hppa1.0*-*-*) path="hppa"; extra_functions="udiv_qrnnd" ;;
+ hppa*-*-*) # assume pa7100
+ path="hppa/hppa1_1/pa7100 hppa/hppa1_1 hppa"
+ extra_functions="udiv_qrnnd" ;;
+ cray2-cray-unicos* | [xy]mp-cray-unicos* | [ctj]90-cray-unicos*)
+ path="cray" ;;
+ alphaev5-*-*) path="alpha/ev5 alpha"; extra_functions="udiv_qrnnd" ;;
+ alpha*-*-*) path="alpha"; extra_functions="udiv_qrnnd" ;;
+ am29000*-*-*) path="am29000" ;;
+ a29k*-*-*) path="am29000" ;;
+
+# Intel x86 configurations
+ i[34]86*-*-linuxaout* | i[34]86*-*-linuxoldld* | \
+ i[34]86*-*-*bsd*) # x86 running BSD or Linux with a.out
+ echo '#define BSD_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/x86/syntax.h"' >>asm-syntax.h
+ path="x86" ;;
+ i[56]86*-*-linuxaout* | pentium-*-linuxaout* | pentiumpro-*-linuxaout* | \
+ i[56]86*-*-linuxoldld* | pentium-*-linuxoldld* | pentiumpro-*-linuxoldld* | \
+ i[56]86*-*-*bsd* | pentium-*-*bsd* | pentiumpro-*-*bsd*)
+ echo '#define BSD_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/x86/syntax.h"' >>asm-syntax.h
+ path="x86/pentium x86" ;;
+ i[34]86*-*-*) # x86 with ELF/SysV format
+ echo '#define ELF_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/x86/syntax.h"' >>asm-syntax.h
+ path="x86" ;;
+ i[56]86*-*-* | pentium-*-* | pentiumpro-*-*) # x86 with ELF/SysV format
+ echo '#define ELF_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/x86/syntax.h"' >>asm-syntax.h
+ path="x86/pentium x86" ;;
+
+# Motorola 68k configurations. Let m68k mean 68020-68040.
+# mc68000 or mc68060 configurations need to be specified explicitly
+ m680[234]0*-*-linuxaout* | m68k*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k/mc68020 m68k" ;;
+ m68060*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k" ;;
+ m680[234]0*-*-linux* | m68k*-*-linux*)
+ echo '#define ELF_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k/mc68020 m68k" ;;
+ m68060*-*-linux*)
+ echo '#define ELF_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k" ;;
+ m68000*-*-* | m68060*-*-*)
+ echo '#define MIT_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k/mc68000" ;;
+ m680[234]0*-*-* | m68k*-*-*)
+ echo '#define MIT_SYNTAX' >asm-syntax.h
+ echo '#include "'$srcdir'/m68k/syntax.h"' >>asm-syntax.h
+ path="m68k/mc68020 m68k" ;;
+
+ i960*-*-*) path="i960" ;;
+ m88k*-*-* | m88k*-*-*) path="m88k" ;;
+ m88110*-*-*) path="m88k/mc88110 m88k" ;;
+ ns32k*-*-*) path="n32k" ;;
+ ppc601-*-*) path="power powerpc32" ;;
+ ppc620-*-* | powerpc64*-*-*) path="powerpc64" ;;
+ ppc60[234]*-*-* | powerpc*-*-*) path="powerpc32" ;;
+ pyramid-*-*) path="pyr" ;;
+ rs6000-*-* | power-*-* | power2-*-*)
+ path="power"; extra_functions="udiv_w_sdiv" ;;
+ sh-*-*) path="sh" ;;
+ sh2-*-*) path="sh/sh2 sh" ;;
+ mips[34]*-*-*) path="mips3" ;;
+ mips*-*-irix6*) path="mips3" ;;
+ mips*-*-*) path="mips2" ;;
+ vax*-*-*) path="vax"; extra_functions="udiv_w_sdiv" ;;
+ z8000x*-*-*) path="z8000x"; extra_functions="udiv_w_sdiv" ;;
+ z8000*-*-*) path="z8000"; extra_functions="udiv_w_sdiv" ;;
+ clipper*-*-*) path="clipper" ;;
+ *-*-*) ;;
+esac
+
+case "${target}" in
+ *-*-linuxaout* | *-*-linuxoldld*) config=bsd.h ;;
+ *-sysv* | *-solaris* | *-*-linux*) config="sysv.h" ;;
+ *) config="bsd.h" ;;
+esac
+
+case "${target}" in
+ i[3456]86*-*-*bsd* | i[3456]86*-*-linuxaout* | i[3456]86*-*-linuxoldld* | \
+ pentium-*-*bsd* | pentium-*-linuxaout* | pentium-*-linuxoldld* | \
+ pentiumpro-*-*bsd* | pentiumpro-*-linuxaout* | pentiumpro-*-linuxoldld*)
+ target_makefile_frag=config/t-oldgas ;;
+ rs6000-*-aix[456789]* | rs6000-*-aix3.2.[456789])
+ target_makefile_frag=config/t-pwr-aix ;;
+ ppc601-*-aix[456789]* | ppc601-*-aix3.2.[456789] | \
+ ppc60[234]*-*-aix[456789]* | ppc60[234]*-*-aix3.2.[456789] | \
+ powerpc*-*-aix[456789]* | powerpc*-*-aix3.2.[456789])
+ target_makefile_frag=config/t-ppc-aix ;;
+esac
+
+
+functions="${extra_functions} inlines add_n addmul_1 cmp divmod_1 \
+ divrem divrem_1 dump lshift mod_1 mul mul_1 mul_n random2 rshift sqrtrem \
+ sub_n submul_1 get_str set_str scan0 scan1 popcount hamdist gcd_1 \
+ pre_mod_1 perfsqr bdivmod gcd gcdext"
+
+path="$path generic"
+mpn_objects=
+
+for fn in $functions ; do
+ mpn_objects="$mpn_objects $fn.o"
+ for dir in $path ; do
+ rm -f $fn.[Ssc]
+ if test -f $srcdir/$dir/$fn.S ; then
+ files="$files $dir/$fn.S"
+ links="$links $fn.S"
+ break
+ elif test -f $srcdir/$dir/$fn.s ; then
+ files="$files $dir/$fn.s"
+ links="$links $fn.s"
+ break
+ elif test -f $srcdir/$dir/$fn.c ; then
+ files="$files $dir/$fn.c"
+ links="$links $fn.c"
+ break
+ fi
+ done
+done
+
+for dir in $path ; do
+ rm -f gmp-mparam.h
+ if test -f $srcdir/$dir/gmp-mparam.h ; then
+ files="$files $dir/gmp-mparam.h"
+ links="$links gmp-mparam.h"
+ break
+ fi
+done
+
+links="sysdep.h $links"
+files="$config $files"
+
+mpn_links=$links
+
+# post-target:
+
+sed <Makefile >Makefile.tmp \
+ -e "s/MPN_LINKS = .*/MPN_LINKS =${mpn_links}/" \
+ -e "s/MPN_OBJECTS = .*/MPN_OBJECTS =${mpn_objects}/"
+
+mv Makefile.tmp Makefile
diff --git a/gnu/lib/libgmp/mpn/generic/add_n.c b/gnu/lib/libgmp/mpn/generic/add_n.c
new file mode 100644
index 0000000..9d71df1
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/add_n.c
@@ -0,0 +1,62 @@
+/* mpn_add_n -- Add two limb vectors of equal, non-zero length.
+
+Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+#if __STDC__
+mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+mpn_add_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x + y; /* add other addend */
+ cy = (y < x) + cy; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/addmul_1.c b/gnu/lib/libgmp/mpn/generic/addmul_1.c
new file mode 100644
index 0000000..3a5e214
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/addmul_1.c
@@ -0,0 +1,65 @@
+/* mpn_addmul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR
+ by S2_LIMB, add the S1_SIZE least significant limbs of the product to the
+ limb vector pointed to by RES_PTR. Return the most significant limb of
+ the product, adjusted for carry-out from the addition.
+
+Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_addmul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+ register mp_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += (prod_low < x);
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/bdivmod.c b/gnu/lib/libgmp/mpn/generic/bdivmod.c
new file mode 100644
index 0000000..f095288
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/bdivmod.c
@@ -0,0 +1,129 @@
+/* mpn/bdivmod.c: mpn_bdivmod for computing U/V mod 2^d.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* q_high = mpn_bdivmod (qp, up, usize, vp, vsize, d).
+
+ Puts the low d/BITS_PER_MP_LIMB limbs of Q = U / V mod 2^d at qp, and
+ returns the high d%BITS_PER_MP_LIMB bits of Q as the result.
+
+ Also, U - Q * V mod 2^(usize*BITS_PER_MP_LIMB) is placed at up. Since the
+ low d/BITS_PER_MP_LIMB limbs of this difference are zero, the code allows
+ the limb vectors at qp to overwrite the low limbs at up, provided qp <= up.
+
+ Preconditions:
+ 1. V is odd.
+ 2. usize * BITS_PER_MP_LIMB >= d.
+ 3. If Q and U overlap, qp <= up.
+
+ Ken Weber (kweber@mat.ufrgs.br, kweber@mcs.kent.edu)
+
+ Funding for this work has been partially provided by Conselho Nacional
+ de Desenvolvimento Cienti'fico e Tecnolo'gico (CNPq) do Brazil, Grant
+ 301314194-2, and was done while I was a visiting reseacher in the Instituto
+ de Matema'tica at Universidade Federal do Rio Grande do Sul (UFRGS).
+
+ References:
+ T. Jebelean, An algorithm for exact division, Journal of Symbolic
+ Computation, v. 15, 1993, pp. 169-180.
+
+ K. Weber, The accelerated integer GCD algorithm, ACM Transactions on
+ Mathematical Software, v. 21 (March), 1995, pp. 111-122. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+#if __STDC__
+mpn_bdivmod (mp_ptr qp, mp_ptr up, mp_size_t usize,
+ mp_srcptr vp, mp_size_t vsize, unsigned long int d)
+#else
+mpn_bdivmod (qp, up, usize, vp, vsize, d)
+ mp_ptr qp;
+ mp_ptr up;
+ mp_size_t usize;
+ mp_srcptr vp;
+ mp_size_t vsize;
+ unsigned long int d;
+#endif
+{
+ /* Cache for v_inv is used to make mpn_accelgcd faster. */
+ static mp_limb_t previous_low_vlimb = 0;
+ static mp_limb_t v_inv; /* 1/V mod 2^BITS_PER_MP_LIMB. */
+
+ if (vp[0] != previous_low_vlimb) /* Cache miss; compute v_inv. */
+ {
+ mp_limb_t v = previous_low_vlimb = vp[0];
+ mp_limb_t make_zero = 1;
+ mp_limb_t two_i = 1;
+ v_inv = 0;
+ do
+ {
+ while ((two_i & make_zero) == 0)
+ two_i <<= 1, v <<= 1;
+ v_inv += two_i;
+ make_zero -= v;
+ }
+ while (make_zero);
+ }
+
+ /* Need faster computation for some common cases in mpn_accelgcd. */
+ if (usize == 2 && vsize == 2 &&
+ (d == BITS_PER_MP_LIMB || d == 2*BITS_PER_MP_LIMB))
+ {
+ mp_limb_t hi, lo;
+ mp_limb_t q = up[0] * v_inv;
+ umul_ppmm (hi, lo, q, vp[0]);
+ up[0] = 0, up[1] -= hi + q*vp[1], qp[0] = q;
+ if (d == 2*BITS_PER_MP_LIMB)
+ q = up[1] * v_inv, up[1] = 0, qp[1] = q;
+ return 0;
+ }
+
+ /* Main loop. */
+ while (d >= BITS_PER_MP_LIMB)
+ {
+ mp_limb_t q = up[0] * v_inv;
+ mp_limb_t b = mpn_submul_1 (up, vp, MIN (usize, vsize), q);
+ if (usize > vsize)
+ mpn_sub_1 (up + vsize, up + vsize, usize - vsize, b);
+ d -= BITS_PER_MP_LIMB;
+ up += 1, usize -= 1;
+ *qp++ = q;
+ }
+
+ if (d)
+ {
+ mp_limb_t b;
+ mp_limb_t q = (up[0] * v_inv) & (((mp_limb_t)1<<d) - 1);
+ switch (q)
+ {
+ case 0: return 0;
+ case 1: b = mpn_sub_n (up, up, vp, MIN (usize, vsize)); break;
+ default: b = mpn_submul_1 (up, vp, MIN (usize, vsize), q); break;
+ }
+ if (usize > vsize)
+ mpn_sub_1 (up + vsize, up + vsize, usize - vsize, b);
+ return q;
+ }
+
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/cmp.c b/gnu/lib/libgmp/mpn/generic/cmp.c
new file mode 100644
index 0000000..4e9c60d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/cmp.c
@@ -0,0 +1,56 @@
+/* mpn_cmp -- Compare two low-level natural-number integers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ There are no restrictions on the relative sizes of
+ the two arguments.
+ Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. */
+
+int
+#if __STDC__
+mpn_cmp (mp_srcptr op1_ptr, mp_srcptr op2_ptr, mp_size_t size)
+#else
+mpn_cmp (op1_ptr, op2_ptr, size)
+ mp_srcptr op1_ptr;
+ mp_srcptr op2_ptr;
+ mp_size_t size;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t op1_word, op2_word;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if (op1_word != op2_word)
+ goto diff;
+ }
+ return 0;
+ diff:
+ /* This can *not* be simplified to
+ op2_word - op2_word
+ since that expression might give signed overflow. */
+ return (op1_word > op2_word) ? 1 : -1;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/divmod_1.c b/gnu/lib/libgmp/mpn/generic/divmod_1.c
new file mode 100644
index 0000000..f93841f
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/divmod_1.c
@@ -0,0 +1,208 @@
+/* mpn_divmod_1(quot_ptr, dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+ QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ here (not udiv_qrnnd). */
+
+mp_limb_t
+#if __STDC__
+mpn_divmod_1 (mp_ptr quot_ptr,
+ mp_srcptr dividend_ptr, mp_size_t dividend_size,
+ mp_limb_t divisor_limb)
+#else
+mpn_divmod_1 (quot_ptr, dividend_ptr, dividend_size, divisor_limb)
+ mp_ptr quot_ptr;
+ mp_srcptr dividend_ptr;
+ mp_size_t dividend_size;
+ mp_limb_t divisor_limb;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t n1, n0, r;
+ int dummy;
+
+ /* ??? Should this be handled at all? Rely on callers? */
+ if (dividend_size == 0)
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ dividend is large, pre-invert the divisor, and use
+ only multiplications in the inner loop. */
+
+ /* This test should be read:
+ Does it ever help to use udiv_qrnnd_preinv?
+ && Does what we save compensate for the inversion overhead? */
+ if (UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME)
+ {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ mp_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ most significant bit (with weight 2**N) implicit. */
+
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (divisor_limb << 1 == 0)
+ divisor_limb_inverted = ~(mp_limb_t) 0;
+ else
+ udiv_qrnnd (divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less... */
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ udiv_qrnnd_preinv (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else
+ {
+ mp_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ most significant bit (with weight 2**N) implicit. */
+
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (divisor_limb << 1 == 0)
+ divisor_limb_inverted = ~(mp_limb_t) 0;
+ else
+ udiv_qrnnd (divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ {
+ quot_ptr[i] = 0;
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (quot_ptr[i], r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else
+ {
+ if (UDIV_NEEDS_NORMALIZATION)
+ {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less... */
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ it, or because DIVISOR_LIMB is already normalized. */
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ {
+ quot_ptr[i] = 0;
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i], r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/divrem.c b/gnu/lib/libgmp/mpn/generic/divrem.c
new file mode 100644
index 0000000..1fe865a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/divrem.c
@@ -0,0 +1,245 @@
+/* mpn_divrem -- Divide natural numbers, producing both remainder and
+ quotient.
+
+Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
+ the NSIZE-DSIZE least significant quotient limbs at QP
+ and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
+ non-zero, generate that many fraction bits and append them after the
+ other quotient limbs.
+ Return the most significant limb of the quotient, this is always 0 or 1.
+
+ Preconditions:
+ 0. NSIZE >= DSIZE.
+ 1. The most significant bit of the divisor must be set.
+ 2. QP must either not overlap with the input operands at all, or
+ QP + DSIZE >= NP must hold true. (This means that it's
+ possible to put the quotient in the high part of NUM, right after the
+ remainder in NUM.
+ 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero. */
+
+mp_limb_t
+#if __STDC__
+mpn_divrem (mp_ptr qp, mp_size_t qextra_limbs,
+ mp_ptr np, mp_size_t nsize,
+ mp_srcptr dp, mp_size_t dsize)
+#else
+mpn_divrem (qp, qextra_limbs, np, nsize, dp, dsize)
+ mp_ptr qp;
+ mp_size_t qextra_limbs;
+ mp_ptr np;
+ mp_size_t nsize;
+ mp_srcptr dp;
+ mp_size_t dsize;
+#endif
+{
+ mp_limb_t most_significant_q_limb = 0;
+
+ switch (dsize)
+ {
+ case 0:
+ /* We are asked to divide by zero, so go ahead and do it! (To make
+ the compiler not remove this statement, return the value.) */
+ return 1 / dsize;
+
+ case 1:
+ {
+ mp_size_t i;
+ mp_limb_t n1;
+ mp_limb_t d;
+
+ d = dp[0];
+ n1 = np[nsize - 1];
+
+ if (n1 >= d)
+ {
+ n1 -= d;
+ most_significant_q_limb = 1;
+ }
+
+ qp += qextra_limbs;
+ for (i = nsize - 2; i >= 0; i--)
+ udiv_qrnnd (qp[i], n1, n1, np[i], d);
+ qp -= qextra_limbs;
+
+ for (i = qextra_limbs - 1; i >= 0; i--)
+ udiv_qrnnd (qp[i], n1, n1, 0, d);
+
+ np[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mp_size_t i;
+ mp_limb_t n1, n0, n2;
+ mp_limb_t d1, d0;
+
+ np += nsize - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ n1 = np[1];
+ n0 = np[0];
+
+ if (n1 >= d1 && (n1 > d1 || n0 >= d0))
+ {
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ most_significant_q_limb = 1;
+ }
+
+ for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--)
+ {
+ mp_limb_t q;
+ mp_limb_t r;
+
+ if (i >= qextra_limbs)
+ np--;
+ else
+ np[0] = 0;
+
+ if (n1 == d1)
+ {
+ /* Q should be either 111..111 or 111..110. Need special
+ treatment of this rare case as normal division would
+ give overflow. */
+ q = ~(mp_limb_t) 0;
+
+ r = n0 + d1;
+ if (r < d1) /* Carry in the addition? */
+ {
+ add_ssaaaa (n1, n0, r - d0, np[0], 0, d0);
+ qp[i] = q;
+ continue;
+ }
+ n1 = d0 - (d0 != 0);
+ n0 = -d0;
+ }
+ else
+ {
+ udiv_qrnnd (q, r, n1, n0, d1);
+ umul_ppmm (n1, n0, d0, q);
+ }
+
+ n2 = np[0];
+ q_test:
+ if (n1 > r || (n1 == r && n0 > n2))
+ {
+ /* The estimated Q was too large. */
+ q--;
+
+ sub_ddmmss (n1, n0, n1, n0, 0, d0);
+ r += d1;
+ if (r >= d1) /* If not carry, test Q again. */
+ goto q_test;
+ }
+
+ qp[i] = q;
+ sub_ddmmss (n1, n0, r, n2, n1, n0);
+ }
+ np[1] = n1;
+ np[0] = n0;
+ }
+ break;
+
+ default:
+ {
+ mp_size_t i;
+ mp_limb_t dX, d1, n0;
+
+ np += nsize - dsize;
+ dX = dp[dsize - 1];
+ d1 = dp[dsize - 2];
+ n0 = np[dsize - 1];
+
+ if (n0 >= dX)
+ {
+ if (n0 > dX || mpn_cmp (np, dp, dsize - 1) >= 0)
+ {
+ mpn_sub_n (np, np, dp, dsize);
+ n0 = np[dsize - 1];
+ most_significant_q_limb = 1;
+ }
+ }
+
+ for (i = qextra_limbs + nsize - dsize - 1; i >= 0; i--)
+ {
+ mp_limb_t q;
+ mp_limb_t n1, n2;
+ mp_limb_t cy_limb;
+
+ if (i >= qextra_limbs)
+ {
+ np--;
+ n2 = np[dsize];
+ }
+ else
+ {
+ n2 = np[dsize - 1];
+ MPN_COPY_DECR (np + 1, np, dsize);
+ np[0] = 0;
+ }
+
+ if (n0 == dX)
+ /* This might over-estimate q, but it's probably not worth
+ the extra code here to find out. */
+ q = ~(mp_limb_t) 0;
+ else
+ {
+ mp_limb_t r;
+
+ udiv_qrnnd (q, r, n0, np[dsize - 1], dX);
+ umul_ppmm (n1, n0, d1, q);
+
+ while (n1 > r || (n1 == r && n0 > np[dsize - 2]))
+ {
+ q--;
+ r += dX;
+ if (r < dX) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ /* Possible optimization: We already have (q * n0) and (1 * n1)
+ after the calculation of q. Taking advantage of that, we
+ could make this loop make two iterations less. */
+
+ cy_limb = mpn_submul_1 (np, dp, dsize, q);
+
+ if (n2 != cy_limb)
+ {
+ mpn_add_n (np, np, dp, dsize);
+ q--;
+ }
+
+ qp[i] = q;
+ n0 = np[dsize - 1];
+ }
+ }
+ }
+
+ return most_significant_q_limb;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/divrem_1.c b/gnu/lib/libgmp/mpn/generic/divrem_1.c
new file mode 100644
index 0000000..d213267
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/divrem_1.c
@@ -0,0 +1,58 @@
+/* mpn_divrem_1(quot_ptr, qsize, dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+ QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+#if __STDC__
+mpn_divrem_1 (mp_ptr qp, mp_size_t qsize,
+ mp_srcptr dividend_ptr, mp_size_t dividend_size,
+ mp_limb_t divisor_limb)
+#else
+mpn_divrem_1 (qp, qsize, dividend_ptr, dividend_size, divisor_limb)
+ mp_ptr qp;
+ mp_size_t qsize;
+ mp_srcptr dividend_ptr;
+ mp_size_t dividend_size;
+ mp_limb_t divisor_limb;
+#endif
+{
+ mp_limb_t rlimb;
+ long i;
+
+ /* Develop integer part of quotient. */
+ rlimb = mpn_divmod_1 (qp + qsize, dividend_ptr, dividend_size, divisor_limb);
+
+ if (qsize != 0)
+ {
+ for (i = qsize - 1; i >= 0; i--)
+ udiv_qrnnd (qp[i], rlimb, rlimb, 0, divisor_limb);
+ }
+ return rlimb;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/dump.c b/gnu/lib/libgmp/mpn/generic/dump.c
new file mode 100644
index 0000000..a5831c4
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/dump.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+mpn_dump (ptr, size)
+ mp_srcptr ptr;
+ mp_size_t size;
+{
+ if (size == 0)
+ printf ("0\n");
+ {
+ while (size)
+ {
+ size--;
+ printf ("%0*lX", (int) (2 * BYTES_PER_MP_LIMB), ptr[size]);
+ }
+ printf ("\n");
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/gcd.c b/gnu/lib/libgmp/mpn/generic/gcd.c
new file mode 100644
index 0000000..8c2bbf0
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/gcd.c
@@ -0,0 +1,402 @@
+/* mpn/gcd.c: mpn_gcd for gcd of two odd integers.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* Integer greatest common divisor of two unsigned integers, using
+ the accelerated algorithm (see reference below).
+
+ mp_size_t mpn_gcd (vp, vsize, up, usize).
+
+ Preconditions [U = (up, usize) and V = (vp, vsize)]:
+
+ 1. V is odd.
+ 2. numbits(U) >= numbits(V).
+
+ Both U and V are destroyed by the operation. The result is left at vp,
+ and its size is returned.
+
+ Ken Weber (kweber@mat.ufrgs.br, kweber@mcs.kent.edu)
+
+ Funding for this work has been partially provided by Conselho Nacional
+ de Desenvolvimento Cienti'fico e Tecnolo'gico (CNPq) do Brazil, Grant
+ 301314194-2, and was done while I was a visiting reseacher in the Instituto
+ de Matema'tica at Universidade Federal do Rio Grande do Sul (UFRGS).
+
+ Refer to
+ K. Weber, The accelerated integer GCD algorithm, ACM Transactions on
+ Mathematical Software, v. 21 (March), 1995, pp. 111-122. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* If MIN (usize, vsize) > ACCEL_THRESHOLD, then the accelerated algorithm is
+ used, otherwise the binary algorithm is used. This may be adjusted for
+ different architectures. */
+#ifndef ACCEL_THRESHOLD
+#define ACCEL_THRESHOLD 4
+#endif
+
+/* When U and V differ in size by more than BMOD_THRESHOLD, the accelerated
+ algorithm reduces using the bmod operation. Otherwise, the k-ary reduction
+ is used. 0 <= BMOD_THRESHOLD < BITS_PER_MP_LIMB. */
+enum
+ {
+ BMOD_THRESHOLD = BITS_PER_MP_LIMB/2
+ };
+
+#define SIGN_BIT (~(~(mp_limb_t)0 >> 1))
+
+
+#define SWAP_LIMB(UL, VL) do{mp_limb_t __l=(UL);(UL)=(VL);(VL)=__l;}while(0)
+#define SWAP_PTR(UP, VP) do{mp_ptr __p=(UP);(UP)=(VP);(VP)=__p;}while(0)
+#define SWAP_SZ(US, VS) do{mp_size_t __s=(US);(US)=(VS);(VS)=__s;}while(0)
+#define SWAP_MPN(UP, US, VP, VS) do{SWAP_PTR(UP,VP);SWAP_SZ(US,VS);}while(0)
+
+/* Use binary algorithm to compute V <-- GCD (V, U) for usize, vsize == 2.
+ Both U and V must be odd. */
+static __gmp_inline mp_size_t
+#if __STDC__
+gcd_2 (mp_ptr vp, mp_srcptr up)
+#else
+gcd_2 (vp, up)
+ mp_ptr vp;
+ mp_srcptr up;
+#endif
+{
+ mp_limb_t u0, u1, v0, v1;
+ mp_size_t vsize;
+
+ u0 = up[0], u1 = up[1], v0 = vp[0], v1 = vp[1];
+
+ while (u1 != v1 && u0 != v0)
+ {
+ unsigned long int r;
+ if (u1 > v1)
+ {
+ u1 -= v1 + (u0 < v0), u0 -= v0;
+ count_trailing_zeros (r, u0);
+ u0 = u1 << (BITS_PER_MP_LIMB - r) | u0 >> r;
+ u1 >>= r;
+ }
+ else /* u1 < v1. */
+ {
+ v1 -= u1 + (v0 < u0), v0 -= u0;
+ count_trailing_zeros (r, v0);
+ v0 = v1 << (BITS_PER_MP_LIMB - r) | v0 >> r;
+ v1 >>= r;
+ }
+ }
+
+ vp[0] = v0, vp[1] = v1, vsize = 1 + (v1 != 0);
+
+ /* If U == V == GCD, done. Otherwise, compute GCD (V, |U - V|). */
+ if (u1 == v1 && u0 == v0)
+ return vsize;
+
+ v0 = (u0 == v0) ? (u1 > v1) ? u1-v1 : v1-u1 : (u0 > v0) ? u0-v0 : v0-u0;
+ vp[0] = mpn_gcd_1 (vp, vsize, v0);
+
+ return 1;
+}
+
+/* The function find_a finds 0 < N < 2^BITS_PER_MP_LIMB such that there exists
+ 0 < |D| < 2^BITS_PER_MP_LIMB, and N == D * C mod 2^(2*BITS_PER_MP_LIMB).
+ In the reference article, D was computed along with N, but it is better to
+ compute D separately as D <-- N / C mod 2^(BITS_PER_MP_LIMB + 1), treating
+ the result as a twos' complement signed integer.
+
+ Initialize N1 to C mod 2^(2*BITS_PER_MP_LIMB). According to the reference
+ article, N2 should be initialized to 2^(2*BITS_PER_MP_LIMB), but we use
+ 2^(2*BITS_PER_MP_LIMB) - N1 to start the calculations within double
+ precision. If N2 > N1 initially, the first iteration of the while loop
+ will swap them. In all other situations, N1 >= N2 is maintained. */
+
+static __gmp_inline mp_limb_t
+#if __STDC__
+find_a (mp_srcptr cp)
+#else
+find_a (cp)
+ mp_srcptr cp;
+#endif
+{
+ unsigned long int leading_zero_bits = 0;
+
+ mp_limb_t n1_l = cp[0]; /* N1 == n1_h * 2^BITS_PER_MP_LIMB + n1_l. */
+ mp_limb_t n1_h = cp[1];
+
+ mp_limb_t n2_l = -n1_l; /* N2 == n2_h * 2^BITS_PER_MP_LIMB + n2_l. */
+ mp_limb_t n2_h = ~n1_h;
+
+ /* Main loop. */
+ while (n2_h) /* While N2 >= 2^BITS_PER_MP_LIMB. */
+ {
+ /* N1 <-- N1 % N2. */
+ if ((SIGN_BIT >> leading_zero_bits & n2_h) == 0)
+ {
+ unsigned long int i;
+ count_leading_zeros (i, n2_h);
+ i -= leading_zero_bits, leading_zero_bits += i;
+ n2_h = n2_h<<i | n2_l>>(BITS_PER_MP_LIMB - i), n2_l <<= i;
+ do
+ {
+ if (n1_h > n2_h || (n1_h == n2_h && n1_l >= n2_l))
+ n1_h -= n2_h + (n1_l < n2_l), n1_l -= n2_l;
+ n2_l = n2_l>>1 | n2_h<<(BITS_PER_MP_LIMB - 1), n2_h >>= 1;
+ i -= 1;
+ }
+ while (i);
+ }
+ if (n1_h > n2_h || (n1_h == n2_h && n1_l >= n2_l))
+ n1_h -= n2_h + (n1_l < n2_l), n1_l -= n2_l;
+
+ SWAP_LIMB (n1_h, n2_h);
+ SWAP_LIMB (n1_l, n2_l);
+ }
+
+ return n2_l;
+}
+
+mp_size_t
+#if __STDC__
+mpn_gcd (mp_ptr gp, mp_ptr vp, mp_size_t vsize, mp_ptr up, mp_size_t usize)
+#else
+mpn_gcd (gp, vp, vsize, up, usize)
+ mp_ptr gp;
+ mp_ptr vp;
+ mp_size_t vsize;
+ mp_ptr up;
+ mp_size_t usize;
+#endif
+{
+ mp_ptr orig_vp = vp;
+ mp_size_t orig_vsize = vsize;
+ int binary_gcd_ctr; /* Number of times binary gcd will execute. */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* Use accelerated algorithm if vsize is over ACCEL_THRESHOLD.
+ Two EXTRA limbs for U and V are required for kary reduction. */
+ if (vsize > ACCEL_THRESHOLD)
+ {
+ unsigned long int vbitsize, d;
+ mp_ptr orig_up = up;
+ mp_size_t orig_usize = usize;
+ mp_ptr anchor_up = (mp_ptr) TMP_ALLOC ((usize + 2) * BYTES_PER_MP_LIMB);
+
+ MPN_COPY (anchor_up, orig_up, usize);
+ up = anchor_up;
+
+ count_leading_zeros (d, up[usize-1]);
+ d = usize * BITS_PER_MP_LIMB - d;
+ count_leading_zeros (vbitsize, vp[vsize-1]);
+ vbitsize = vsize * BITS_PER_MP_LIMB - vbitsize;
+ d = d - vbitsize + 1;
+
+ /* Use bmod reduction to quickly discover whether V divides U. */
+ up[usize++] = 0; /* Insert leading zero. */
+ mpn_bdivmod (up, up, usize, vp, vsize, d);
+
+ /* Now skip U/V mod 2^d and any low zero limbs. */
+ d /= BITS_PER_MP_LIMB, up += d, usize -= d;
+ while (usize != 0 && up[0] == 0)
+ up++, usize--;
+
+ if (usize == 0) /* GCD == ORIG_V. */
+ goto done;
+
+ vp = (mp_ptr) TMP_ALLOC ((vsize + 2) * BYTES_PER_MP_LIMB);
+ MPN_COPY (vp, orig_vp, vsize);
+
+ do /* Main loop. */
+ {
+ if (up[usize-1] & SIGN_BIT) /* U < 0; take twos' compl. */
+ {
+ mp_size_t i;
+ anchor_up[0] = -up[0];
+ for (i = 1; i < usize; i++)
+ anchor_up[i] = ~up[i];
+ up = anchor_up;
+ }
+
+ MPN_NORMALIZE_NOT_ZERO (up, usize);
+
+ if ((up[0] & 1) == 0) /* Result even; remove twos. */
+ {
+ unsigned long int r;
+ count_trailing_zeros (r, up[0]);
+ mpn_rshift (anchor_up, up, usize, r);
+ usize -= (anchor_up[usize-1] == 0);
+ }
+ else if (anchor_up != up)
+ MPN_COPY (anchor_up, up, usize);
+
+ SWAP_MPN (anchor_up, usize, vp, vsize);
+ up = anchor_up;
+
+ if (vsize <= 2) /* Kary can't handle < 2 limbs and */
+ break; /* isn't efficient for == 2 limbs. */
+
+ d = vbitsize;
+ count_leading_zeros (vbitsize, vp[vsize-1]);
+ vbitsize = vsize * BITS_PER_MP_LIMB - vbitsize;
+ d = d - vbitsize + 1;
+
+ if (d > BMOD_THRESHOLD) /* Bmod reduction. */
+ {
+ up[usize++] = 0;
+ mpn_bdivmod (up, up, usize, vp, vsize, d);
+ d /= BITS_PER_MP_LIMB, up += d, usize -= d;
+ }
+ else /* Kary reduction. */
+ {
+ mp_limb_t bp[2], cp[2];
+
+ /* C <-- V/U mod 2^(2*BITS_PER_MP_LIMB). */
+ cp[0] = vp[0], cp[1] = vp[1];
+ mpn_bdivmod (cp, cp, 2, up, 2, 2*BITS_PER_MP_LIMB);
+
+ /* U <-- find_a (C) * U. */
+ up[usize] = mpn_mul_1 (up, up, usize, find_a (cp));
+ usize++;
+
+ /* B <-- A/C == U/V mod 2^(BITS_PER_MP_LIMB + 1).
+ bp[0] <-- U/V mod 2^BITS_PER_MP_LIMB and
+ bp[1] <-- ( (U - bp[0] * V)/2^BITS_PER_MP_LIMB ) / V mod 2 */
+ bp[0] = up[0], bp[1] = up[1];
+ mpn_bdivmod (bp, bp, 2, vp, 2, BITS_PER_MP_LIMB);
+ bp[1] &= 1; /* Since V is odd, division is unnecessary. */
+
+ up[usize++] = 0;
+ if (bp[1]) /* B < 0: U <-- U + (-B) * V. */
+ {
+ mp_limb_t c = mpn_addmul_1 (up, vp, vsize, -bp[0]);
+ mpn_add_1 (up + vsize, up + vsize, usize - vsize, c);
+ }
+ else /* B >= 0: U <-- U - B * V. */
+ {
+ mp_limb_t b = mpn_submul_1 (up, vp, vsize, bp[0]);
+ mpn_sub_1 (up + vsize, up + vsize, usize - vsize, b);
+ }
+
+ up += 2, usize -= 2; /* At least two low limbs are zero. */
+ }
+
+ /* Must remove low zero limbs before complementing. */
+ while (usize != 0 && up[0] == 0)
+ up++, usize--;
+ }
+ while (usize);
+
+ /* Compute GCD (ORIG_V, GCD (ORIG_U, V)). Binary will execute twice. */
+ up = orig_up, usize = orig_usize;
+ binary_gcd_ctr = 2;
+ }
+ else
+ binary_gcd_ctr = 1;
+
+ /* Finish up with the binary algorithm. Executes once or twice. */
+ for ( ; binary_gcd_ctr--; up = orig_vp, usize = orig_vsize)
+ {
+ if (usize > 2) /* First make U close to V in size. */
+ {
+ unsigned long int vbitsize, d;
+ count_leading_zeros (d, up[usize-1]);
+ d = usize * BITS_PER_MP_LIMB - d;
+ count_leading_zeros (vbitsize, vp[vsize-1]);
+ vbitsize = vsize * BITS_PER_MP_LIMB - vbitsize;
+ d = d - vbitsize - 1;
+ if (d != -(unsigned long int)1 && d > 2)
+ {
+ mpn_bdivmod (up, up, usize, vp, vsize, d); /* Result > 0. */
+ d /= (unsigned long int)BITS_PER_MP_LIMB, up += d, usize -= d;
+ }
+ }
+
+ /* Start binary GCD. */
+ do
+ {
+ mp_size_t zeros;
+
+ /* Make sure U is odd. */
+ MPN_NORMALIZE (up, usize);
+ while (up[0] == 0)
+ up += 1, usize -= 1;
+ if ((up[0] & 1) == 0)
+ {
+ unsigned long int r;
+ count_trailing_zeros (r, up[0]);
+ mpn_rshift (up, up, usize, r);
+ usize -= (up[usize-1] == 0);
+ }
+
+ /* Keep usize >= vsize. */
+ if (usize < vsize)
+ SWAP_MPN (up, usize, vp, vsize);
+
+ if (usize <= 2) /* Double precision. */
+ {
+ if (vsize == 1)
+ vp[0] = mpn_gcd_1 (up, usize, vp[0]);
+ else
+ vsize = gcd_2 (vp, up);
+ break; /* Binary GCD done. */
+ }
+
+ /* Count number of low zero limbs of U - V. */
+ for (zeros = 0; up[zeros] == vp[zeros] && ++zeros != vsize; )
+ continue;
+
+ /* If U < V, swap U and V; in any case, subtract V from U. */
+ if (zeros == vsize) /* Subtract done. */
+ up += zeros, usize -= zeros;
+ else if (usize == vsize)
+ {
+ mp_size_t size = vsize;
+ do
+ size--;
+ while (up[size] == vp[size]);
+ if (up[size] < vp[size]) /* usize == vsize. */
+ SWAP_PTR (up, vp);
+ up += zeros, usize = size + 1 - zeros;
+ mpn_sub_n (up, up, vp + zeros, usize);
+ }
+ else
+ {
+ mp_size_t size = vsize - zeros;
+ up += zeros, usize -= zeros;
+ if (mpn_sub_n (up, up, vp + zeros, size))
+ {
+ while (up[size] == 0) /* Propagate borrow. */
+ up[size++] = -(mp_limb_t)1;
+ up[size] -= 1;
+ }
+ }
+ }
+ while (usize); /* End binary GCD. */
+ }
+
+done:
+ if (vp != gp)
+ MPN_COPY (gp, vp, vsize);
+ TMP_FREE (marker);
+ return vsize;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/gcd_1.c b/gnu/lib/libgmp/mpn/generic/gcd_1.c
new file mode 100644
index 0000000..ebcdfb5
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/gcd_1.c
@@ -0,0 +1,73 @@
+/* mpn_gcd_1 --
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Does not work for U == 0 or V == 0. It would be tough to make it work for
+ V == 0 since gcd(x,0) = x, and U does not generally fit in an mp_limb_t. */
+
+mp_limb_t
+mpn_gcd_1 (up, size, vlimb)
+ mp_srcptr up;
+ mp_size_t size;
+ mp_limb_t vlimb;
+{
+ mp_limb_t ulimb;
+ unsigned long int u_low_zero_bits, v_low_zero_bits;
+
+ if (size > 1)
+ {
+ ulimb = mpn_mod_1 (up, size, vlimb);
+ if (ulimb == 0)
+ return vlimb;
+ }
+ else
+ ulimb = up[0];
+
+ /* Need to eliminate low zero bits. */
+ count_trailing_zeros (u_low_zero_bits, ulimb);
+ ulimb >>= u_low_zero_bits;
+
+ count_trailing_zeros (v_low_zero_bits, vlimb);
+ vlimb >>= v_low_zero_bits;
+
+ while (ulimb != vlimb)
+ {
+ if (ulimb > vlimb)
+ {
+ ulimb -= vlimb;
+ do
+ ulimb >>= 1;
+ while ((ulimb & 1) == 0);
+ }
+ else /* vlimb > ulimb. */
+ {
+ vlimb -= ulimb;
+ do
+ vlimb >>= 1;
+ while ((vlimb & 1) == 0);
+ }
+ }
+
+ return ulimb << MIN (u_low_zero_bits, v_low_zero_bits);
+}
diff --git a/gnu/lib/libgmp/mpn/generic/gcdext.c b/gnu/lib/libgmp/mpn/generic/gcdext.c
new file mode 100644
index 0000000..245e20a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/gcdext.c
@@ -0,0 +1,441 @@
+/* mpn_gcdext -- Extended Greatest Common Divisor.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef EXTEND
+#define EXTEND 1
+#endif
+
+#if STAT
+int arr[BITS_PER_MP_LIMB];
+#endif
+
+#define SGN(A) (((A) < 0) ? -1 : ((A) > 0))
+
+/* Idea 1: After we have performed a full division, don't shift operands back,
+ but instead account for the extra factors-of-2 thus introduced.
+ Idea 2: Simple generalization to use divide-and-conquer would give us an
+ algorithm that runs faster than O(n^2).
+ Idea 3: The input numbers need less space as the computation progresses,
+ while the s0 and s1 variables need more space. To save space, we
+ could make them share space, and have the latter variables grow
+ into the former. */
+
+/* Precondition: U >= V. */
+
+mp_size_t
+#if EXTEND
+#if __STDC__
+mpn_gcdext (mp_ptr gp, mp_ptr s0p,
+ mp_ptr up, mp_size_t size, mp_ptr vp, mp_size_t vsize)
+#else
+mpn_gcdext (gp, s0p, up, size, vp, vsize)
+ mp_ptr gp;
+ mp_ptr s0p;
+ mp_ptr up;
+ mp_size_t size;
+ mp_ptr vp;
+ mp_size_t vsize;
+#endif
+#else
+#if __STDC__
+mpn_gcd (mp_ptr gp,
+ mp_ptr up, mp_size_t size, mp_ptr vp, mp_size_t vsize)
+#else
+mpn_gcd (gp, up, size, vp, vsize)
+ mp_ptr gp;
+ mp_ptr up;
+ mp_size_t size;
+ mp_ptr vp;
+ mp_size_t vsize;
+#endif
+#endif
+{
+ mp_limb_t uh, vh;
+ mp_limb_signed_t A, B, C, D;
+ int cnt;
+ mp_ptr tp, wp;
+#if RECORD
+ mp_limb_signed_t min = 0, max = 0;
+#endif
+#if EXTEND
+ mp_ptr s1p;
+ mp_ptr orig_s0p = s0p;
+ mp_size_t ssize, orig_size = size;
+ TMP_DECL (mark);
+
+ TMP_MARK (mark);
+
+ tp = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ wp = (mp_ptr) TMP_ALLOC ((size + 1) * BYTES_PER_MP_LIMB);
+ s1p = (mp_ptr) TMP_ALLOC (size * BYTES_PER_MP_LIMB);
+
+ MPN_ZERO (s0p, size);
+ MPN_ZERO (s1p, size);
+
+ s0p[0] = 1;
+ s1p[0] = 0;
+ ssize = 1;
+#endif
+
+ if (size > vsize)
+ {
+ /* Normalize V (and shift up U the same amount). */
+ count_leading_zeros (cnt, vp[vsize - 1]);
+ if (cnt != 0)
+ {
+ mp_limb_t cy;
+ mpn_lshift (vp, vp, vsize, cnt);
+ cy = mpn_lshift (up, up, size, cnt);
+ up[size] = cy;
+ size += cy != 0;
+ }
+
+ mpn_divmod (up + vsize, up, size, vp, vsize);
+#if EXTEND
+ /* This is really what it boils down to in this case... */
+ s0p[0] = 0;
+ s1p[0] = 1;
+#endif
+ size = vsize;
+ if (cnt != 0)
+ {
+ mpn_rshift (up, up, size, cnt);
+ mpn_rshift (vp, vp, size, cnt);
+ }
+ {
+ mp_ptr xp;
+ xp = up; up = vp; vp = xp;
+ }
+ }
+
+ for (;;)
+ {
+ /* Figure out exact size of V. */
+ vsize = size;
+ MPN_NORMALIZE (vp, vsize);
+ if (vsize <= 1)
+ break;
+
+ /* Make UH be the most significant limb of U, and make VH be
+ corresponding bits from V. */
+ uh = up[size - 1];
+ vh = vp[size - 1];
+ count_leading_zeros (cnt, uh);
+ if (cnt != 0)
+ {
+ uh = (uh << cnt) | (up[size - 2] >> (BITS_PER_MP_LIMB - cnt));
+ vh = (vh << cnt) | (vp[size - 2] >> (BITS_PER_MP_LIMB - cnt));
+ }
+
+#if 0
+ /* For now, only handle BITS_PER_MP_LIMB-1 bits. This makes
+ room for sign bit. */
+ uh >>= 1;
+ vh >>= 1;
+#endif
+ A = 1;
+ B = 0;
+ C = 0;
+ D = 1;
+
+ for (;;)
+ {
+ mp_limb_signed_t q, T;
+ if (vh + C == 0 || vh + D == 0)
+ break;
+
+ q = (uh + A) / (vh + C);
+ if (q != (uh + B) / (vh + D))
+ break;
+
+ T = A - q * C;
+ A = C;
+ C = T;
+ T = B - q * D;
+ B = D;
+ D = T;
+ T = uh - q * vh;
+ uh = vh;
+ vh = T;
+ }
+
+#if RECORD
+ min = MIN (A, min); min = MIN (B, min);
+ min = MIN (C, min); min = MIN (D, min);
+ max = MAX (A, max); max = MAX (B, max);
+ max = MAX (C, max); max = MAX (D, max);
+#endif
+
+ if (B == 0)
+ {
+ mp_limb_t qh;
+ mp_size_t i;
+
+ /* This is quite rare. I.e., optimize something else! */
+
+ /* Normalize V (and shift up U the same amount). */
+ count_leading_zeros (cnt, vp[vsize - 1]);
+ if (cnt != 0)
+ {
+ mp_limb_t cy;
+ mpn_lshift (vp, vp, vsize, cnt);
+ cy = mpn_lshift (up, up, size, cnt);
+ up[size] = cy;
+ size += cy != 0;
+ }
+
+ qh = mpn_divmod (up + vsize, up, size, vp, vsize);
+#if EXTEND
+ MPN_COPY (tp, s0p, ssize);
+ for (i = 0; i < size - vsize; i++)
+ {
+ mp_limb_t cy;
+ cy = mpn_addmul_1 (tp + i, s1p, ssize, up[vsize + i]);
+ if (cy != 0)
+ tp[ssize++] = cy;
+ }
+ if (qh != 0)
+ {
+ mp_limb_t cy;
+ abort ();
+ /* XXX since qh == 1, mpn_addmul_1 is overkill */
+ cy = mpn_addmul_1 (tp + size - vsize, s1p, ssize, qh);
+ if (cy != 0)
+ tp[ssize++] = cy;
+ }
+#if 0
+ MPN_COPY (s0p, s1p, ssize); /* should be old ssize, kind of */
+ MPN_COPY (s1p, tp, ssize);
+#else
+ {
+ mp_ptr xp;
+ xp = s0p; s0p = s1p; s1p = xp;
+ xp = s1p; s1p = tp; tp = xp;
+ }
+#endif
+#endif
+ size = vsize;
+ if (cnt != 0)
+ {
+ mpn_rshift (up, up, size, cnt);
+ mpn_rshift (vp, vp, size, cnt);
+ }
+
+ {
+ mp_ptr xp;
+ xp = up; up = vp; vp = xp;
+ }
+ MPN_NORMALIZE (up, size);
+ }
+ else
+ {
+ /* T = U*A + V*B
+ W = U*C + V*D
+ U = T
+ V = W */
+
+ if (SGN(A) == SGN(B)) /* should be different sign */
+ abort ();
+ if (SGN(C) == SGN(D)) /* should be different sign */
+ abort ();
+#if STAT
+ { mp_limb_t x;
+ x = ABS (A) | ABS (B) | ABS (C) | ABS (D);
+ count_leading_zeros (cnt, x);
+ arr[BITS_PER_MP_LIMB - cnt]++; }
+#endif
+ if (A == 0)
+ {
+ if (B != 1) abort ();
+ MPN_COPY (tp, vp, size);
+ }
+ else
+ {
+ if (A < 0)
+ {
+ mpn_mul_1 (tp, vp, size, B);
+ mpn_submul_1 (tp, up, size, -A);
+ }
+ else
+ {
+ mpn_mul_1 (tp, up, size, A);
+ mpn_submul_1 (tp, vp, size, -B);
+ }
+ }
+ if (C < 0)
+ {
+ mpn_mul_1 (wp, vp, size, D);
+ mpn_submul_1 (wp, up, size, -C);
+ }
+ else
+ {
+ mpn_mul_1 (wp, up, size, C);
+ mpn_submul_1 (wp, vp, size, -D);
+ }
+
+ {
+ mp_ptr xp;
+ xp = tp; tp = up; up = xp;
+ xp = wp; wp = vp; vp = xp;
+ }
+
+#if EXTEND
+ { mp_limb_t cy;
+ MPN_ZERO (tp, orig_size);
+ if (A == 0)
+ {
+ if (B != 1) abort ();
+ MPN_COPY (tp, s1p, ssize);
+ }
+ else
+ {
+ if (A < 0)
+ {
+ cy = mpn_mul_1 (tp, s1p, ssize, B);
+ cy += mpn_addmul_1 (tp, s0p, ssize, -A);
+ }
+ else
+ {
+ cy = mpn_mul_1 (tp, s0p, ssize, A);
+ cy += mpn_addmul_1 (tp, s1p, ssize, -B);
+ }
+ if (cy != 0)
+ tp[ssize++] = cy;
+ }
+ MPN_ZERO (wp, orig_size);
+ if (C < 0)
+ {
+ cy = mpn_mul_1 (wp, s1p, ssize, D);
+ cy += mpn_addmul_1 (wp, s0p, ssize, -C);
+ }
+ else
+ {
+ cy = mpn_mul_1 (wp, s0p, ssize, C);
+ cy += mpn_addmul_1 (wp, s1p, ssize, -D);
+ }
+ if (cy != 0)
+ wp[ssize++] = cy;
+ }
+ {
+ mp_ptr xp;
+ xp = tp; tp = s0p; s0p = xp;
+ xp = wp; wp = s1p; s1p = xp;
+ }
+#endif
+#if 0 /* Is it a win to remove multiple zeros here? */
+ MPN_NORMALIZE (up, size);
+#else
+ if (up[size - 1] == 0)
+ size--;
+#endif
+ }
+ }
+
+#if RECORD
+ printf ("min: %ld\n", min);
+ printf ("max: %ld\n", max);
+#endif
+
+ if (vsize == 0)
+ {
+ if (gp != up)
+ MPN_COPY (gp, up, size);
+#if EXTEND
+ if (orig_s0p != s0p)
+ MPN_COPY (orig_s0p, s0p, ssize);
+#endif
+ TMP_FREE (mark);
+ return size;
+ }
+ else
+ {
+ mp_limb_t vl, ul, t;
+#if EXTEND
+ mp_limb_t cy;
+ mp_size_t i;
+#endif
+ vl = vp[0];
+#if EXTEND
+ t = mpn_divmod_1 (wp, up, size, vl);
+ MPN_COPY (tp, s0p, ssize);
+ for (i = 0; i < size; i++)
+ {
+ cy = mpn_addmul_1 (tp + i, s1p, ssize, wp[i]);
+ if (cy != 0)
+ tp[ssize++] = cy;
+ }
+#if 0
+ MPN_COPY (s0p, s1p, ssize);
+ MPN_COPY (s1p, tp, ssize);
+#else
+ {
+ mp_ptr xp;
+ xp = s0p; s0p = s1p; s1p = xp;
+ xp = s1p; s1p = tp; tp = xp;
+ }
+#endif
+#else
+ t = mpn_mod_1 (up, size, vl);
+#endif
+ ul = vl;
+ vl = t;
+ while (vl != 0)
+ {
+ mp_limb_t t;
+#if EXTEND
+ mp_limb_t q, cy;
+ q = ul / vl;
+ t = ul - q*vl;
+
+ MPN_COPY (tp, s0p, ssize);
+ cy = mpn_addmul_1 (tp, s1p, ssize, q);
+ if (cy != 0)
+ tp[ssize++] = cy;
+#if 0
+ MPN_COPY (s0p, s1p, ssize);
+ MPN_COPY (s1p, tp, ssize);
+#else
+ {
+ mp_ptr xp;
+ xp = s0p; s0p = s1p; s1p = xp;
+ xp = s1p; s1p = tp; tp = xp;
+ }
+#endif
+
+#else
+ t = ul % vl;
+#endif
+ ul = vl;
+ vl = t;
+ }
+ gp[0] = ul;
+#if EXTEND
+ if (orig_s0p != s0p)
+ MPN_COPY (orig_s0p, s0p, ssize);
+#endif
+ TMP_FREE (mark);
+ return 1;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/get_str.c b/gnu/lib/libgmp/mpn/generic/get_str.c
new file mode 100644
index 0000000..0e7fc60
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/get_str.c
@@ -0,0 +1,211 @@
+/* mpn_get_str -- Convert a MSIZE long limb vector pointed to by MPTR
+ to a printable string in STR in base BASE.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Convert the limb vector pointed to by MPTR and MSIZE long to a
+ char array, using base BASE for the result array. Store the
+ result in the character array STR. STR must point to an array with
+ space for the largest possible number represented by a MSIZE long
+ limb vector + 1 extra character.
+
+ The result is NOT in Ascii, to convert it to printable format, add
+ '0' or 'A' depending on the base and range.
+
+ Return the number of digits in the result string.
+ This may include some leading zeros.
+
+ The limb vector pointed to by MPTR is clobbered. */
+
+size_t
+mpn_get_str (str, base, mptr, msize)
+ unsigned char *str;
+ int base;
+ mp_ptr mptr;
+ mp_size_t msize;
+{
+ mp_limb_t big_base;
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ int normalization_steps;
+#endif
+#if UDIV_TIME > 2 * UMUL_TIME
+ mp_limb_t big_base_inverted;
+#endif
+ unsigned int dig_per_u;
+ mp_size_t out_len;
+ register unsigned char *s;
+
+ big_base = __mp_bases[base].big_base;
+
+ s = str;
+
+ /* Special case zero, as the code below doesn't handle it. */
+ if (msize == 0)
+ {
+ s[0] = 0;
+ return 1;
+ }
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* The base is a power of 2. Make conversion from most
+ significant side. */
+ mp_limb_t n1, n0;
+ register int bits_per_digit = big_base;
+ register int x;
+ register int bit_pos;
+ register int i;
+
+ n1 = mptr[msize - 1];
+ count_leading_zeros (x, n1);
+
+ /* BIT_POS should be R when input ends in least sign. nibble,
+ R + bits_per_digit * n when input ends in n:th least significant
+ nibble. */
+
+ {
+ int bits;
+
+ bits = BITS_PER_MP_LIMB * msize - x;
+ x = bits % bits_per_digit;
+ if (x != 0)
+ bits += bits_per_digit - x;
+ bit_pos = bits - (msize - 1) * BITS_PER_MP_LIMB;
+ }
+
+ /* Fast loop for bit output. */
+ i = msize - 1;
+ for (;;)
+ {
+ bit_pos -= bits_per_digit;
+ while (bit_pos >= 0)
+ {
+ *s++ = (n1 >> bit_pos) & ((1 << bits_per_digit) - 1);
+ bit_pos -= bits_per_digit;
+ }
+ i--;
+ if (i < 0)
+ break;
+ n0 = (n1 << -bit_pos) & ((1 << bits_per_digit) - 1);
+ n1 = mptr[i];
+ bit_pos += BITS_PER_MP_LIMB;
+ *s++ = n0 | (n1 >> bit_pos);
+ }
+
+ *s = 0;
+
+ return s - str;
+ }
+ else
+ {
+ /* General case. The base is not a power of 2. Make conversion
+ from least significant end. */
+
+ /* If udiv_qrnnd only handles divisors with the most significant bit
+ set, prepare BIG_BASE for being a divisor by shifting it to the
+ left exactly enough to set the most significant bit. */
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ count_leading_zeros (normalization_steps, big_base);
+ big_base <<= normalization_steps;
+#if UDIV_TIME > 2 * UMUL_TIME
+ /* Get the fixed-point approximation to 1/(BIG_BASE << NORMALIZATION_STEPS). */
+ big_base_inverted = __mp_bases[base].big_base_inverted;
+#endif
+#endif
+
+ dig_per_u = __mp_bases[base].chars_per_limb;
+ out_len = ((size_t) msize * BITS_PER_MP_LIMB
+ * __mp_bases[base].chars_per_bit_exactly) + 1;
+ s += out_len;
+
+ while (msize != 0)
+ {
+ int i;
+ mp_limb_t n0, n1;
+
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ /* If we shifted BIG_BASE above, shift the dividend too, to get
+ the right quotient. We need to do this every loop,
+ since the intermediate quotients are OK, but the quotient from
+ one turn in the loop is going to be the dividend in the
+ next turn, and the dividend needs to be up-shifted. */
+ if (normalization_steps != 0)
+ {
+ n0 = mpn_lshift (mptr, mptr, msize, normalization_steps);
+
+ /* If the shifting gave a carry out limb, store it and
+ increase the length. */
+ if (n0 != 0)
+ {
+ mptr[msize] = n0;
+ msize++;
+ }
+ }
+#endif
+
+ /* Divide the number at TP with BIG_BASE to get a quotient and a
+ remainder. The remainder is our new digit in base BIG_BASE. */
+ i = msize - 1;
+ n1 = mptr[i];
+
+ if (n1 >= big_base)
+ n1 = 0;
+ else
+ {
+ msize--;
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = mptr[i];
+#if UDIV_TIME > 2 * UMUL_TIME
+ udiv_qrnnd_preinv (mptr[i], n1, n1, n0, big_base, big_base_inverted);
+#else
+ udiv_qrnnd (mptr[i], n1, n1, n0, big_base);
+#endif
+ }
+
+#if UDIV_NEEDS_NORMALIZATION || UDIV_TIME > 2 * UMUL_TIME
+ /* If we shifted above (at previous UDIV_NEEDS_NORMALIZATION tests)
+ the remainder will be up-shifted here. Compensate. */
+ n1 >>= normalization_steps;
+#endif
+
+ /* Convert N1 from BIG_BASE to a string of digits in BASE
+ using single precision operations. */
+ for (i = dig_per_u - 1; i >= 0; i--)
+ {
+ *--s = n1 % base;
+ n1 /= base;
+ if (n1 == 0 && msize == 0)
+ break;
+ }
+ }
+
+ while (s != str)
+ *--s = 0;
+ return out_len;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/gmp-mparam.h b/gnu/lib/libgmp/mpn/generic/gmp-mparam.h
new file mode 100644
index 0000000..7c88557
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/gmp-mparam.h
@@ -0,0 +1,27 @@
+/* gmp-mparam.h -- Compiler/machine parameter header file.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#define BITS_PER_MP_LIMB 32
+#define BYTES_PER_MP_LIMB 4
+#define BITS_PER_LONGINT 32
+#define BITS_PER_INT 32
+#define BITS_PER_SHORTINT 16
+#define BITS_PER_CHAR 8
diff --git a/gnu/lib/libgmp/mpn/generic/hamdist.c b/gnu/lib/libgmp/mpn/generic/hamdist.c
new file mode 100644
index 0000000..2190b63
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/hamdist.c
@@ -0,0 +1,88 @@
+/* mpn_hamdist --
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined __GNUC__
+#if defined __sparc_v9__ && BITS_PER_MP_LIMB == 64
+#define popc_limb(a) \
+ ({ \
+ DItype __res; \
+ asm ("popc %1,%0" : "=r" (__res) : "rI" (a)); \
+ __res; \
+ })
+#endif
+#endif
+
+#ifndef popc_limb
+
+/* Cool population count of a mp_limb_t.
+ You have to figure out how this works, I won't tell you! */
+
+static inline unsigned int
+popc_limb (x)
+ mp_limb_t x;
+{
+#if BITS_PER_MP_LIMB == 64
+ /* We have to go into some trouble to define these constants.
+ (For mp_limb_t being `long long'.) */
+ mp_limb_t cnst;
+ cnst = 0x55555555L | ((mp_limb_t) 0x55555555L << BITS_PER_MP_LIMB/2);
+ x = ((x & ~cnst) >> 1) + (x & cnst);
+ cnst = 0x33333333L | ((mp_limb_t) 0x33333333L << BITS_PER_MP_LIMB/2);
+ x = ((x & ~cnst) >> 2) + (x & cnst);
+ cnst = 0x0f0f0f0fL | ((mp_limb_t) 0x0f0f0f0fL << BITS_PER_MP_LIMB/2);
+ x = ((x >> 4) + x) & cnst;
+ x = ((x >> 8) + x);
+ x = ((x >> 16) + x);
+ x = ((x >> 32) + x) & 0xff;
+#endif
+#if BITS_PER_MP_LIMB == 32
+ x = ((x >> 1) & 0x55555555L) + (x & 0x55555555L);
+ x = ((x >> 2) & 0x33333333L) + (x & 0x33333333L);
+ x = ((x >> 4) + x) & 0x0f0f0f0fL;
+ x = ((x >> 8) + x);
+ x = ((x >> 16) + x) & 0xff;
+#endif
+ return x;
+}
+#endif
+
+unsigned long int
+#if __STDC__
+mpn_hamdist (mp_srcptr up, mp_srcptr vp, mp_size_t size)
+#else
+mpn_hamdist (up, vp, size)
+ register mp_srcptr up;
+ register mp_srcptr vp;
+ register mp_size_t size;
+#endif
+{
+ unsigned long int hamdist;
+ mp_size_t i;
+
+ hamdist = 0;
+ for (i = 0; i < size; i++)
+ hamdist += popc_limb (up[i] ^ vp[i]);
+
+ return hamdist;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/inlines.c b/gnu/lib/libgmp/mpn/generic/inlines.c
new file mode 100644
index 0000000..dca305e
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/inlines.c
@@ -0,0 +1,3 @@
+#define _FORCE_INLINES
+#define _EXTERN_INLINE /* empty */
+#include "gmp.h"
diff --git a/gnu/lib/libgmp/mpn/generic/lshift.c b/gnu/lib/libgmp/mpn/generic/lshift.c
new file mode 100644
index 0000000..e244bc5
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/lshift.c
@@ -0,0 +1,87 @@
+/* mpn_lshift -- Shift left low level.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ and store the USIZE least significant digits of the result at WP.
+ Return the bits shifted out from the most significant digit.
+
+ Argument constraints:
+ 1. 0 < CNT < BITS_PER_MP_LIMB
+ 2. If the result is to be written over the input, WP must be >= UP.
+*/
+
+mp_limb_t
+#if __STDC__
+mpn_lshift (register mp_ptr wp,
+ register mp_srcptr up, mp_size_t usize,
+ register unsigned int cnt)
+#else
+mpn_lshift (wp, up, usize, cnt)
+ register mp_ptr wp;
+ register mp_srcptr up;
+ mp_size_t usize;
+ register unsigned int cnt;
+#endif
+{
+ register mp_limb_t high_limb, low_limb;
+ register unsigned sh_1, sh_2;
+ register mp_size_t i;
+ mp_limb_t retval;
+
+#ifdef DEBUG
+ if (usize == 0 || cnt == 0)
+ abort ();
+#endif
+
+ sh_1 = cnt;
+#if 0
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from high end to low end, to allow specified input/output
+ overlapping. */
+ for (i = usize - 1; i >= 0; i--)
+ wp[i] = up[i];
+ }
+ return 0;
+ }
+#endif
+
+ wp += 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while (--i >= 0)
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/mod_1.c b/gnu/lib/libgmp/mpn/generic/mod_1.c
new file mode 100644
index 0000000..314d11b
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/mod_1.c
@@ -0,0 +1,197 @@
+/* mpn_mod_1(dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ here (not udiv_qrnnd). */
+
+mp_limb_t
+#if __STDC__
+mpn_mod_1 (mp_srcptr dividend_ptr, mp_size_t dividend_size,
+ mp_limb_t divisor_limb)
+#else
+mpn_mod_1 (dividend_ptr, dividend_size, divisor_limb)
+ mp_srcptr dividend_ptr;
+ mp_size_t dividend_size;
+ mp_limb_t divisor_limb;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t n1, n0, r;
+ int dummy;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if (dividend_size == 0)
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ dividend is large, pre-invert the divisor, and use
+ only multiplications in the inner loop. */
+
+ /* This test should be read:
+ Does it ever help to use udiv_qrnnd_preinv?
+ && Does what we save compensate for the inversion overhead? */
+ if (UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME)
+ {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ mp_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ most significant bit (with weight 2**N) implicit. */
+
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (divisor_limb << 1 == 0)
+ divisor_limb_inverted = ~(mp_limb_t) 0;
+ else
+ udiv_qrnnd (divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less... */
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ udiv_qrnnd_preinv (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else
+ {
+ mp_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ most significant bit (with weight 2**N) implicit. */
+
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (divisor_limb << 1 == 0)
+ divisor_limb_inverted = ~(mp_limb_t) 0;
+ else
+ udiv_qrnnd (divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (dummy, r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else
+ {
+ if (UDIV_NEEDS_NORMALIZATION)
+ {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less... */
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ it, or because DIVISOR_LIMB is already normalized. */
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/mul.c b/gnu/lib/libgmp/mpn/generic/mul.c
new file mode 100644
index 0000000..dcf8cb4
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/mul.c
@@ -0,0 +1,152 @@
+/* mpn_mul -- Multiply two natural numbers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ and v (pointed to by VP, with VSIZE limbs), and store the result at
+ PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ operands are normalized. Return the most significant limb of the
+ result.
+
+ NOTE: The space pointed to by PRODP is overwritten before finished
+ with U and V, so overlap is an error.
+
+ Argument constraints:
+ 1. USIZE >= VSIZE.
+ 2. PRODP != UP and PRODP != VP, i.e. the destination
+ must be distinct from the multiplier and the multiplicand. */
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ value which is good on most machines. */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 32
+#endif
+
+mp_limb_t
+#if __STDC__
+mpn_mul (mp_ptr prodp,
+ mp_srcptr up, mp_size_t usize,
+ mp_srcptr vp, mp_size_t vsize)
+#else
+mpn_mul (prodp, up, usize, vp, vsize)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_srcptr vp;
+ mp_size_t vsize;
+#endif
+{
+ mp_ptr prod_endp = prodp + usize + vsize - 1;
+ mp_limb_t cy;
+ mp_ptr tspace;
+ TMP_DECL (marker);
+
+ if (vsize < KARATSUBA_THRESHOLD)
+ {
+ /* Handle simple cases with traditional multiplication.
+
+ This is the most critical code of the entire function. All
+ multiplies rely on this, both small and huge. Small ones arrive
+ here immediately. Huge ones arrive here as this is the base case
+ for Karatsuba's recursive algorithm below. */
+ mp_size_t i;
+ mp_limb_t cy_limb;
+ mp_limb_t v_limb;
+
+ if (vsize == 0)
+ return 0;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if (v_limb <= 1)
+ {
+ if (v_limb == 1)
+ MPN_COPY (prodp, up, usize);
+ else
+ MPN_ZERO (prodp, usize);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = mpn_mul_1 (prodp, up, usize, v_limb);
+
+ prodp[usize] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++)
+ {
+ v_limb = vp[i];
+ if (v_limb <= 1)
+ {
+ cy_limb = 0;
+ if (v_limb == 1)
+ cy_limb = mpn_add_n (prodp, prodp, up, usize);
+ }
+ else
+ cy_limb = mpn_addmul_1 (prodp, up, usize, v_limb);
+
+ prodp[usize] = cy_limb;
+ prodp++;
+ }
+ return cy_limb;
+ }
+
+ TMP_MARK (marker);
+
+ tspace = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB);
+ MPN_MUL_N_RECURSE (prodp, up, vp, vsize, tspace);
+
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ if (usize >= vsize)
+ {
+ mp_ptr tp = (mp_ptr) TMP_ALLOC (2 * vsize * BYTES_PER_MP_LIMB);
+ do
+ {
+ MPN_MUL_N_RECURSE (tp, up, vp, vsize, tspace);
+ cy = mpn_add_n (prodp, prodp, tp, vsize);
+ mpn_add_1 (prodp + vsize, tp + vsize, vsize, cy);
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ }
+ while (usize >= vsize);
+ }
+
+ /* True: usize < vsize. */
+
+ /* Make life simple: Recurse. */
+
+ if (usize != 0)
+ {
+ mpn_mul (tspace, vp, vsize, up, usize);
+ cy = mpn_add_n (prodp, prodp, tspace, vsize);
+ mpn_add_1 (prodp + vsize, tspace + vsize, usize, cy);
+ }
+
+ TMP_FREE (marker);
+ return *prod_endp;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/mul_1.c b/gnu/lib/libgmp/mpn/generic/mul_1.c
new file mode 100644
index 0000000..2de680a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/mul_1.c
@@ -0,0 +1,59 @@
+/* mpn_mul_1 -- Multiply a limb vector with a single limb and
+ store the product in a second limb vector.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/mul_n.c b/gnu/lib/libgmp/mpn/generic/mul_n.c
new file mode 100644
index 0000000..b38e8ad
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/mul_n.c
@@ -0,0 +1,401 @@
+/* mpn_mul_n -- Multiply two natural numbers of length n.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
+ both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
+ always stored. Return the most significant limb.
+
+ Argument constraints:
+ 1. PRODP != UP and PRODP != VP, i.e. the destination
+ must be distinct from the multiplier and the multiplicand. */
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ value which is good on most machines. */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 32
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
+#if KARATSUBA_THRESHOLD < 2
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 2
+#endif
+
+/* Handle simple cases with traditional multiplication.
+
+ This is the most critical code of multiplication. All multiplies rely
+ on this, both small and huge. Small ones arrive here immediately. Huge
+ ones arrive here as this is the base case for Karatsuba's recursive
+ algorithm below. */
+
+void
+#if __STDC__
+impn_mul_n_basecase (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
+#else
+impn_mul_n_basecase (prodp, up, vp, size)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_srcptr vp;
+ mp_size_t size;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t cy_limb;
+ mp_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if (v_limb <= 1)
+ {
+ if (v_limb == 1)
+ MPN_COPY (prodp, up, size);
+ else
+ MPN_ZERO (prodp, size);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = mpn_mul_1 (prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < size; i++)
+ {
+ v_limb = vp[i];
+ if (v_limb <= 1)
+ {
+ cy_limb = 0;
+ if (v_limb == 1)
+ cy_limb = mpn_add_n (prodp, prodp, up, size);
+ }
+ else
+ cy_limb = mpn_addmul_1 (prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+void
+#if __STDC__
+impn_mul_n (mp_ptr prodp,
+ mp_srcptr up, mp_srcptr vp, mp_size_t size, mp_ptr tspace)
+#else
+impn_mul_n (prodp, up, vp, size, tspace)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_srcptr vp;
+ mp_size_t size;
+ mp_ptr tspace;
+#endif
+{
+ if ((size & 1) != 0)
+ {
+ /* The size is odd, the code code below doesn't handle that.
+ Multiply the least significant (size - 1) limbs with a recursive
+ call, and handle the most significant limb of S1 and S2
+ separately. */
+ /* A slightly faster way to do this would be to make the Karatsuba
+ code below behave as if the size were even, and let it check for
+ odd size in the end. I.e., in essence move this code to the end.
+ Doing so would save us a recursive call, and potentially make the
+ stack grow a lot less. */
+
+ mp_size_t esize = size - 1; /* even size */
+ mp_limb_t cy_limb;
+
+ MPN_MUL_N_RECURSE (prodp, up, vp, esize, tspace);
+ cy_limb = mpn_addmul_1 (prodp + esize, up, esize, vp[esize]);
+ prodp[esize + esize] = cy_limb;
+ cy_limb = mpn_addmul_1 (prodp + esize, vp, size, up[esize]);
+
+ prodp[esize + size] = cy_limb;
+ }
+ else
+ {
+ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
+
+ Split U in two pieces, U1 and U0, such that
+ U = U0 + U1*(B**n),
+ and V in V1 and V0, such that
+ V = V0 + V1*(B**n).
+
+ UV is then computed recursively using the identity
+
+ 2n n n n
+ UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ 1 1 1 0 0 1 0 0
+
+ Where B = 2**BITS_PER_MP_LIMB. */
+
+ mp_size_t hsize = size >> 1;
+ mp_limb_t cy;
+ int negflg;
+
+ /*** Product H. ________________ ________________
+ |_____U1 x V1____||____U0 x V0_____| */
+ /* Put result in upper part of PROD and pass low part of TSPACE
+ as new TSPACE. */
+ MPN_MUL_N_RECURSE (prodp + size, up + hsize, vp + hsize, hsize, tspace);
+
+ /*** Product M. ________________
+ |_(U1-U0)(V0-V1)_| */
+ if (mpn_cmp (up + hsize, up, hsize) >= 0)
+ {
+ mpn_sub_n (prodp, up + hsize, up, hsize);
+ negflg = 0;
+ }
+ else
+ {
+ mpn_sub_n (prodp, up, up + hsize, hsize);
+ negflg = 1;
+ }
+ if (mpn_cmp (vp + hsize, vp, hsize) >= 0)
+ {
+ mpn_sub_n (prodp + hsize, vp + hsize, vp, hsize);
+ negflg ^= 1;
+ }
+ else
+ {
+ mpn_sub_n (prodp + hsize, vp, vp + hsize, hsize);
+ /* No change of NEGFLG. */
+ }
+ /* Read temporary operands from low part of PROD.
+ Put result in low part of TSPACE using upper part of TSPACE
+ as new TSPACE. */
+ MPN_MUL_N_RECURSE (tspace, prodp, prodp + hsize, hsize, tspace + size);
+
+ /*** Add/copy product H. */
+ MPN_COPY (prodp + hsize, prodp + size, hsize);
+ cy = mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize);
+
+ /*** Add product M (if NEGFLG M is a negative number). */
+ if (negflg)
+ cy -= mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size);
+ else
+ cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size);
+
+ /*** Product L. ________________ ________________
+ |________________||____U0 x V0_____| */
+ /* Read temporary operands from low part of PROD.
+ Put result in low part of TSPACE using upper part of TSPACE
+ as new TSPACE. */
+ MPN_MUL_N_RECURSE (tspace, up, vp, hsize, tspace + size);
+
+ /*** Add/copy Product L (twice). */
+
+ cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size);
+ if (cy)
+ mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy);
+
+ MPN_COPY (prodp, tspace, hsize);
+ cy = mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if (cy)
+ mpn_add_1 (prodp + size, prodp + size, size, 1);
+ }
+}
+
+void
+#if __STDC__
+impn_sqr_n_basecase (mp_ptr prodp, mp_srcptr up, mp_size_t size)
+#else
+impn_sqr_n_basecase (prodp, up, size)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size_t size;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t cy_limb;
+ mp_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = up[0];
+ if (v_limb <= 1)
+ {
+ if (v_limb == 1)
+ MPN_COPY (prodp, up, size);
+ else
+ MPN_ZERO (prodp, size);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = mpn_mul_1 (prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < size; i++)
+ {
+ v_limb = up[i];
+ if (v_limb <= 1)
+ {
+ cy_limb = 0;
+ if (v_limb == 1)
+ cy_limb = mpn_add_n (prodp, prodp, up, size);
+ }
+ else
+ cy_limb = mpn_addmul_1 (prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+void
+#if __STDC__
+impn_sqr_n (mp_ptr prodp,
+ mp_srcptr up, mp_size_t size, mp_ptr tspace)
+#else
+impn_sqr_n (prodp, up, size, tspace)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size_t size;
+ mp_ptr tspace;
+#endif
+{
+ if ((size & 1) != 0)
+ {
+ /* The size is odd, the code code below doesn't handle that.
+ Multiply the least significant (size - 1) limbs with a recursive
+ call, and handle the most significant limb of S1 and S2
+ separately. */
+ /* A slightly faster way to do this would be to make the Karatsuba
+ code below behave as if the size were even, and let it check for
+ odd size in the end. I.e., in essence move this code to the end.
+ Doing so would save us a recursive call, and potentially make the
+ stack grow a lot less. */
+
+ mp_size_t esize = size - 1; /* even size */
+ mp_limb_t cy_limb;
+
+ MPN_SQR_N_RECURSE (prodp, up, esize, tspace);
+ cy_limb = mpn_addmul_1 (prodp + esize, up, esize, up[esize]);
+ prodp[esize + esize] = cy_limb;
+ cy_limb = mpn_addmul_1 (prodp + esize, up, size, up[esize]);
+
+ prodp[esize + size] = cy_limb;
+ }
+ else
+ {
+ mp_size_t hsize = size >> 1;
+ mp_limb_t cy;
+
+ /*** Product H. ________________ ________________
+ |_____U1 x U1____||____U0 x U0_____| */
+ /* Put result in upper part of PROD and pass low part of TSPACE
+ as new TSPACE. */
+ MPN_SQR_N_RECURSE (prodp + size, up + hsize, hsize, tspace);
+
+ /*** Product M. ________________
+ |_(U1-U0)(U0-U1)_| */
+ if (mpn_cmp (up + hsize, up, hsize) >= 0)
+ {
+ mpn_sub_n (prodp, up + hsize, up, hsize);
+ }
+ else
+ {
+ mpn_sub_n (prodp, up, up + hsize, hsize);
+ }
+
+ /* Read temporary operands from low part of PROD.
+ Put result in low part of TSPACE using upper part of TSPACE
+ as new TSPACE. */
+ MPN_SQR_N_RECURSE (tspace, prodp, hsize, tspace + size);
+
+ /*** Add/copy product H. */
+ MPN_COPY (prodp + hsize, prodp + size, hsize);
+ cy = mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize);
+
+ /*** Add product M (if NEGFLG M is a negative number). */
+ cy -= mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size);
+
+ /*** Product L. ________________ ________________
+ |________________||____U0 x U0_____| */
+ /* Read temporary operands from low part of PROD.
+ Put result in low part of TSPACE using upper part of TSPACE
+ as new TSPACE. */
+ MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
+
+ /*** Add/copy Product L (twice). */
+
+ cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size);
+ if (cy)
+ mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy);
+
+ MPN_COPY (prodp, tspace, hsize);
+ cy = mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if (cy)
+ mpn_add_1 (prodp + size, prodp + size, size, 1);
+ }
+}
+
+/* This should be made into an inline function in gmp.h. */
+inline void
+#if __STDC__
+mpn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
+#else
+mpn_mul_n (prodp, up, vp, size)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_srcptr vp;
+ mp_size_t size;
+#endif
+{
+ TMP_DECL (marker);
+ TMP_MARK (marker);
+ if (up == vp)
+ {
+ if (size < KARATSUBA_THRESHOLD)
+ {
+ impn_sqr_n_basecase (prodp, up, size);
+ }
+ else
+ {
+ mp_ptr tspace;
+ tspace = (mp_ptr) TMP_ALLOC (2 * size * BYTES_PER_MP_LIMB);
+ impn_sqr_n (prodp, up, size, tspace);
+ }
+ }
+ else
+ {
+ if (size < KARATSUBA_THRESHOLD)
+ {
+ impn_mul_n_basecase (prodp, up, vp, size);
+ }
+ else
+ {
+ mp_ptr tspace;
+ tspace = (mp_ptr) TMP_ALLOC (2 * size * BYTES_PER_MP_LIMB);
+ impn_mul_n (prodp, up, vp, size, tspace);
+ }
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpn/generic/perfsqr.c b/gnu/lib/libgmp/mpn/generic/perfsqr.c
new file mode 100644
index 0000000..5a6e2af
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/perfsqr.c
@@ -0,0 +1,138 @@
+/* mpn_perfect_square_p(u,usize) -- Return non-zero if U is a perfect square,
+ zero otherwise.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+#if BITS_PER_MP_LIMB == 32
+#define PP 0xC0CFD797L /* 3 x 5 x 7 x 11 x 13 x ... x 29 */
+#define PP_INVERTED 0x53E5645CL
+#endif
+
+#if BITS_PER_MP_LIMB == 64
+#define PP 0xE221F97C30E94E1DL /* 3 x 5 x 7 x 11 x 13 x ... x 53 */
+#define PP_INVERTED 0x21CFE6CFC938B36BL
+#endif
+
+/* sq_res_0x100[x mod 0x100] == 1 iff x mod 0x100 is a quadratic residue
+ modulo 0x100. */
+static unsigned char const sq_res_0x100[0x100] =
+{
+ 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+};
+
+int
+#if __STDC__
+mpn_perfect_square_p (mp_srcptr up, mp_size_t usize)
+#else
+mpn_perfect_square_p (up, usize)
+ mp_srcptr up;
+ mp_size_t usize;
+#endif
+{
+ mp_limb_t rem;
+ mp_ptr root_ptr;
+ int res;
+ TMP_DECL (marker);
+
+ /* The first test excludes 55/64 (85.9%) of the perfect square candidates
+ in O(1) time. */
+ if ((sq_res_0x100[(unsigned int) up[0] % 0x100] & 1) == 0)
+ return 0;
+
+#if defined (PP)
+ /* The second test excludes 30652543/30808063 (99.5%) of the remaining
+ perfect square candidates in O(n) time. */
+
+ /* Firstly, compute REM = A mod PP. */
+ if (UDIV_TIME > (2 * UMUL_TIME + 6))
+ rem = mpn_preinv_mod_1 (up, usize, (mp_limb_t) PP, (mp_limb_t) PP_INVERTED);
+ else
+ rem = mpn_mod_1 (up, usize, (mp_limb_t) PP);
+
+ /* Now decide if REM is a quadratic residue modulo the factors in PP. */
+
+ /* If A is just a few limbs, computing the square root does not take long
+ time, so things might run faster if we limit this loop according to the
+ size of A. */
+
+#if BITS_PER_MP_LIMB == 64
+ if (((0x12DD703303AED3L >> rem % 53) & 1) == 0)
+ return 0;
+ if (((0x4351B2753DFL >> rem % 47) & 1) == 0)
+ return 0;
+ if (((0x35883A3EE53L >> rem % 43) & 1) == 0)
+ return 0;
+ if (((0x1B382B50737L >> rem % 41) & 1) == 0)
+ return 0;
+ if (((0x165E211E9BL >> rem % 37) & 1) == 0)
+ return 0;
+ if (((0x121D47B7L >> rem % 31) & 1) == 0)
+ return 0;
+#endif
+ if (((0x13D122F3L >> rem % 29) & 1) == 0)
+ return 0;
+ if (((0x5335FL >> rem % 23) & 1) == 0)
+ return 0;
+ if (((0x30AF3L >> rem % 19) & 1) == 0)
+ return 0;
+ if (((0x1A317L >> rem % 17) & 1) == 0)
+ return 0;
+ if (((0x161BL >> rem % 13) & 1) == 0)
+ return 0;
+ if (((0x23BL >> rem % 11) & 1) == 0)
+ return 0;
+ if (((0x017L >> rem % 7) & 1) == 0)
+ return 0;
+ if (((0x13L >> rem % 5) & 1) == 0)
+ return 0;
+ if (((0x3L >> rem % 3) & 1) == 0)
+ return 0;
+#endif
+
+ TMP_MARK (marker);
+
+ /* For the third and last test, we finally compute the square root,
+ to make sure we've really got a perfect square. */
+ root_ptr = (mp_ptr) TMP_ALLOC ((usize + 1) / 2 * BYTES_PER_MP_LIMB);
+
+ /* Iff mpn_sqrtrem returns zero, the square is perfect. */
+ res = ! mpn_sqrtrem (root_ptr, NULL, up, usize);
+ TMP_FREE (marker);
+ return res;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/popcount.c b/gnu/lib/libgmp/mpn/generic/popcount.c
new file mode 100644
index 0000000..c48573a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/popcount.c
@@ -0,0 +1,87 @@
+/* popcount.c
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined __GNUC__
+#if defined __sparc_v9__ && BITS_PER_MP_LIMB == 64
+#define popc_limb(a) \
+ ({ \
+ DItype __res; \
+ asm ("popc %1,%0" : "=r" (__res) : "rI" (a)); \
+ __res; \
+ })
+#endif
+#endif
+
+#ifndef popc_limb
+
+/* Cool population count of a mp_limb_t.
+ You have to figure out how this works, I won't tell you! */
+
+static inline unsigned int
+popc_limb (x)
+ mp_limb_t x;
+{
+#if BITS_PER_MP_LIMB == 64
+ /* We have to go into some trouble to define these constants.
+ (For mp_limb_t being `long long'.) */
+ mp_limb_t cnst;
+ cnst = 0x55555555L | ((mp_limb_t) 0x55555555L << BITS_PER_MP_LIMB/2);
+ x = ((x & ~cnst) >> 1) + (x & cnst);
+ cnst = 0x33333333L | ((mp_limb_t) 0x33333333L << BITS_PER_MP_LIMB/2);
+ x = ((x & ~cnst) >> 2) + (x & cnst);
+ cnst = 0x0f0f0f0fL | ((mp_limb_t) 0x0f0f0f0fL << BITS_PER_MP_LIMB/2);
+ x = ((x >> 4) + x) & cnst;
+ x = ((x >> 8) + x);
+ x = ((x >> 16) + x);
+ x = ((x >> 32) + x) & 0xff;
+#endif
+#if BITS_PER_MP_LIMB == 32
+ x = ((x >> 1) & 0x55555555L) + (x & 0x55555555L);
+ x = ((x >> 2) & 0x33333333L) + (x & 0x33333333L);
+ x = ((x >> 4) + x) & 0x0f0f0f0fL;
+ x = ((x >> 8) + x);
+ x = ((x >> 16) + x) & 0xff;
+#endif
+ return x;
+}
+#endif
+
+unsigned long int
+#if __STDC__
+mpn_popcount (register mp_srcptr p, register mp_size_t size)
+#else
+mpn_popcount (p, size)
+ register mp_srcptr p;
+ register mp_size_t size;
+#endif
+{
+ unsigned long int popcnt;
+ mp_size_t i;
+
+ popcnt = 0;
+ for (i = 0; i < size; i++)
+ popcnt += popc_limb (p[i]);
+
+ return popcnt;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/pre_mod_1.c b/gnu/lib/libgmp/mpn/generic/pre_mod_1.c
new file mode 100644
index 0000000..92d413b
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/pre_mod_1.c
@@ -0,0 +1,69 @@
+/* mpn_preinv_mod_1 (dividend_ptr, dividend_size, divisor_limb,
+ divisor_limb_inverted) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by the normalized DIVISOR_LIMB.
+ DIVISOR_LIMB_INVERTED should be 2^(2*BITS_PER_MP_LIMB) / DIVISOR_LIMB +
+ - 2^BITS_PER_MP_LIMB.
+ Return the single-limb remainder.
+
+Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+mp_limb_t
+#if __STDC__
+mpn_preinv_mod_1 (mp_srcptr dividend_ptr, mp_size_t dividend_size,
+ mp_limb_t divisor_limb, mp_limb_t divisor_limb_inverted)
+#else
+mpn_preinv_mod_1 (dividend_ptr, dividend_size, divisor_limb, divisor_limb_inverted)
+ mp_srcptr dividend_ptr;
+ mp_size_t dividend_size;
+ mp_limb_t divisor_limb;
+ mp_limb_t divisor_limb_inverted;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t n0, r;
+ int dummy;
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (dummy, r, r, n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/random2.c b/gnu/lib/libgmp/mpn/generic/random2.c
new file mode 100644
index 0000000..2954608
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/random2.c
@@ -0,0 +1,93 @@
+/* mpn_random2 -- Generate random numbers with relatively long strings
+ of ones and zeroes. Suitable for border testing.
+
+Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined (__hpux) || defined (alpha__) || defined (__svr4__) || defined (__SVR4)
+/* HPUX lacks random(). DEC OSF/1 1.2 random() returns a double. */
+long mrand48 ();
+static inline long
+random ()
+{
+ return mrand48 ();
+}
+#else
+long random ();
+#endif
+
+/* It's a bit tricky to get this right, so please test the code well
+ if you hack with it. Some early versions of the function produced
+ random numbers with the leading limb == 0, and some versions never
+ made the most significant bit set. */
+
+void
+mpn_random2 (res_ptr, size)
+ mp_ptr res_ptr;
+ mp_size_t size;
+{
+ int n_bits;
+ int bit_pos;
+ mp_size_t limb_pos;
+ unsigned int ran;
+ mp_limb_t limb;
+
+ limb = 0;
+
+ /* Start off in a random bit position in the most significant limb. */
+ bit_pos = random () & (BITS_PER_MP_LIMB - 1);
+
+ /* Least significant bit of RAN chooses string of ones/string of zeroes.
+ Make most significant limb be non-zero by setting bit 0 of RAN. */
+ ran = random () | 1;
+
+ for (limb_pos = size - 1; limb_pos >= 0; )
+ {
+ n_bits = (ran >> 1) % BITS_PER_MP_LIMB + 1;
+ if ((ran & 1) != 0)
+ {
+ /* Generate a string of ones. */
+ if (n_bits >= bit_pos)
+ {
+ res_ptr[limb_pos--] = limb | ((((mp_limb_t) 2) << bit_pos) - 1);
+ bit_pos += BITS_PER_MP_LIMB;
+ limb = (~(mp_limb_t) 0) << (bit_pos - n_bits);
+ }
+ else
+ {
+ limb |= ((((mp_limb_t) 1) << n_bits) - 1) << (bit_pos - n_bits + 1);
+ }
+ }
+ else
+ {
+ /* Generate a string of zeroes. */
+ if (n_bits >= bit_pos)
+ {
+ res_ptr[limb_pos--] = limb;
+ limb = 0;
+ bit_pos += BITS_PER_MP_LIMB;
+ }
+ }
+ bit_pos -= n_bits;
+ ran = random ();
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/rshift.c b/gnu/lib/libgmp/mpn/generic/rshift.c
new file mode 100644
index 0000000..804f9be
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/rshift.c
@@ -0,0 +1,88 @@
+/* mpn_rshift -- Shift right a low-level natural-number integer.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ and store the USIZE least significant limbs of the result at WP.
+ The bits shifted out to the right are returned.
+
+ Argument constraints:
+ 1. 0 < CNT < BITS_PER_MP_LIMB
+ 2. If the result is to be written over the input, WP must be <= UP.
+*/
+
+mp_limb_t
+#if __STDC__
+mpn_rshift (register mp_ptr wp,
+ register mp_srcptr up, mp_size_t usize,
+ register unsigned int cnt)
+#else
+mpn_rshift (wp, up, usize, cnt)
+ register mp_ptr wp;
+ register mp_srcptr up;
+ mp_size_t usize;
+ register unsigned int cnt;
+#endif
+{
+ register mp_limb_t high_limb, low_limb;
+ register unsigned sh_1, sh_2;
+ register mp_size_t i;
+ mp_limb_t retval;
+
+#ifdef DEBUG
+ if (usize == 0 || cnt == 0)
+ abort ();
+#endif
+
+ sh_1 = cnt;
+
+#if 0
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from low end to high end, to allow specified input/output
+ overlapping. */
+ for (i = 0; i < usize; i++)
+ wp[i] = up[i];
+ }
+ return usize;
+ }
+#endif
+
+ wp -= 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+
+ for (i = 1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ wp[i] = low_limb >> sh_1;
+
+ return retval;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/scan0.c b/gnu/lib/libgmp/mpn/generic/scan0.c
new file mode 100644
index 0000000..d6f6580
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/scan0.c
@@ -0,0 +1,62 @@
+/* mpn_scan0 -- Scan from a given bit position for the next clear bit.
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Design issues:
+ 1. What if starting_bit is not within U? Caller's problem?
+ 2. Bit index should be 'unsigned'?
+
+ Argument constraints:
+ 1. U must sooner ot later have a limb with a clear bit.
+ */
+
+unsigned long int
+#if __STDC__
+mpn_scan0 (register mp_srcptr up,
+ register unsigned long int starting_bit)
+#else
+mpn_scan0 (up, starting_bit)
+ register mp_srcptr up;
+ register unsigned long int starting_bit;
+#endif
+{
+ mp_size_t starting_word;
+ mp_limb_t alimb;
+ int cnt;
+ mp_srcptr p;
+
+ /* Start at the word implied by STARTING_BIT. */
+ starting_word = starting_bit / BITS_PER_MP_LIMB;
+ p = up + starting_word;
+ alimb = ~*p++;
+
+ /* Mask off any bits before STARTING_BIT in the first limb. */
+ alimb &= - (mp_limb_t) 1 << (starting_bit % BITS_PER_MP_LIMB);
+
+ while (alimb == 0)
+ alimb = ~*p++;
+
+ count_leading_zeros (cnt, alimb & -alimb);
+ return (p - up) * BITS_PER_MP_LIMB - 1 - cnt;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/scan1.c b/gnu/lib/libgmp/mpn/generic/scan1.c
new file mode 100644
index 0000000..c95d090
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/scan1.c
@@ -0,0 +1,62 @@
+/* mpn_scan1 -- Scan from a given bit position for the next set bit.
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Design issues:
+ 1. What if starting_bit is not within U? Caller's problem?
+ 2. Bit index should be 'unsigned'?
+
+ Argument constraints:
+ 1. U must sooner ot later have a limb != 0.
+ */
+
+unsigned long int
+#if __STDC__
+mpn_scan1 (register mp_srcptr up,
+ register unsigned long int starting_bit)
+#else
+mpn_scan1 (up, starting_bit)
+ register mp_srcptr up;
+ register unsigned long int starting_bit;
+#endif
+{
+ mp_size_t starting_word;
+ mp_limb_t alimb;
+ int cnt;
+ mp_srcptr p;
+
+ /* Start at the word implied by STARTING_BIT. */
+ starting_word = starting_bit / BITS_PER_MP_LIMB;
+ p = up + starting_word;
+ alimb = *p++;
+
+ /* Mask off any bits before STARTING_BIT in the first limb. */
+ alimb &= - (mp_limb_t) 1 << (starting_bit % BITS_PER_MP_LIMB);
+
+ while (alimb == 0)
+ alimb = *p++;
+
+ count_leading_zeros (cnt, alimb & -alimb);
+ return (p - up) * BITS_PER_MP_LIMB - 1 - cnt;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/set_str.c b/gnu/lib/libgmp/mpn/generic/set_str.c
new file mode 100644
index 0000000..424fad3
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/set_str.c
@@ -0,0 +1,154 @@
+/* mpn_set_str (mp_ptr res_ptr, const char *str, size_t str_len, int base)
+ -- Convert a STR_LEN long base BASE byte string pointed to by STR to a
+ limb vector pointed to by RES_PTR. Return the number of limbs in
+ RES_PTR.
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_size_t
+mpn_set_str (xp, str, str_len, base)
+ mp_ptr xp;
+ const unsigned char *str;
+ size_t str_len;
+ int base;
+{
+ mp_size_t size;
+ mp_limb_t big_base;
+ int indigits_per_limb;
+ mp_limb_t res_digit;
+
+ big_base = __mp_bases[base].big_base;
+ indigits_per_limb = __mp_bases[base].chars_per_limb;
+
+/* size = str_len / indigits_per_limb + 1; */
+
+ size = 0;
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* The base is a power of 2. Read the input string from
+ least to most significant character/digit. */
+
+ const unsigned char *s;
+ int next_bitpos;
+ int bits_per_indigit = big_base;
+
+ res_digit = 0;
+ next_bitpos = 0;
+
+ for (s = str + str_len - 1; s >= str; s--)
+ {
+ int inp_digit = *s;
+
+ res_digit |= (mp_limb_t) inp_digit << next_bitpos;
+ next_bitpos += bits_per_indigit;
+ if (next_bitpos >= BITS_PER_MP_LIMB)
+ {
+ xp[size++] = res_digit;
+ next_bitpos -= BITS_PER_MP_LIMB;
+ res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
+ }
+ }
+
+ if (res_digit != 0)
+ xp[size++] = res_digit;
+ }
+ else
+ {
+ /* General case. The base is not a power of 2. */
+
+ size_t i;
+ int j;
+ mp_limb_t cy_limb;
+
+ for (i = indigits_per_limb; i < str_len; i += indigits_per_limb)
+ {
+ res_digit = *str++;
+ if (base == 10)
+ { /* This is a common case.
+ Help the compiler to avoid multiplication. */
+ for (j = 1; j < indigits_per_limb; j++)
+ res_digit = res_digit * 10 + *str++;
+ }
+ else
+ {
+ for (j = 1; j < indigits_per_limb; j++)
+ res_digit = res_digit * base + *str++;
+ }
+
+ if (size == 0)
+ {
+ if (res_digit != 0)
+ {
+ xp[0] = res_digit;
+ size = 1;
+ }
+ }
+ else
+ {
+ cy_limb = mpn_mul_1 (xp, xp, size, big_base);
+ cy_limb += mpn_add_1 (xp, xp, size, res_digit);
+ if (cy_limb != 0)
+ xp[size++] = cy_limb;
+ }
+ }
+
+ big_base = base;
+ res_digit = *str++;
+ if (base == 10)
+ { /* This is a common case.
+ Help the compiler to avoid multiplication. */
+ for (j = 1; j < str_len - (i - indigits_per_limb); j++)
+ {
+ res_digit = res_digit * 10 + *str++;
+ big_base *= 10;
+ }
+ }
+ else
+ {
+ for (j = 1; j < str_len - (i - indigits_per_limb); j++)
+ {
+ res_digit = res_digit * base + *str++;
+ big_base *= base;
+ }
+ }
+
+ if (size == 0)
+ {
+ if (res_digit != 0)
+ {
+ xp[0] = res_digit;
+ size = 1;
+ }
+ }
+ else
+ {
+ cy_limb = mpn_mul_1 (xp, xp, size, big_base);
+ cy_limb += mpn_add_1 (xp, xp, size, res_digit);
+ if (cy_limb != 0)
+ xp[size++] = cy_limb;
+ }
+ }
+
+ return size;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/sqrtrem.c b/gnu/lib/libgmp/mpn/generic/sqrtrem.c
new file mode 100644
index 0000000..539480d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/sqrtrem.c
@@ -0,0 +1,498 @@
+/* mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size)
+
+ Write the square root of {OP_PTR, OP_SIZE} at ROOT_PTR.
+ Write the remainder at REM_PTR, if REM_PTR != NULL.
+ Return the size of the remainder.
+ (The size of the root is always half of the size of the operand.)
+
+ OP_PTR and ROOT_PTR may not point to the same object.
+ OP_PTR and REM_PTR may point to the same object.
+
+ If REM_PTR is NULL, only the root is computed and the return value of
+ the function is 0 if OP is a perfect square, and *any* non-zero number
+ otherwise.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* This code is just correct if "unsigned char" has at least 8 bits. It
+ doesn't help to use CHAR_BIT from limits.h, as the real problem is
+ the static arrays. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Square root algorithm:
+
+ 1. Shift OP (the input) to the left an even number of bits s.t. there
+ are an even number of words and either (or both) of the most
+ significant bits are set. This way, sqrt(OP) has exactly half as
+ many words as OP, and has its most significant bit set.
+
+ 2. Get a 9-bit approximation to sqrt(OP) using the pre-computed tables.
+ This approximation is used for the first single-precision
+ iterations of Newton's method, yielding a full-word approximation
+ to sqrt(OP).
+
+ 3. Perform multiple-precision Newton iteration until we have the
+ exact result. Only about half of the input operand is used in
+ this calculation, as the square root is perfectly determinable
+ from just the higher half of a number. */
+
+/* Define this macro for IEEE P854 machines with a fast sqrt instruction. */
+#if defined __GNUC__ && ! defined __SOFT_FLOAT
+
+#if defined __sparc__
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrtd %1,%0" : "=f" (__sqrt_res) : "f" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#if defined __HAVE_68881__
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrtx %1,%0" : "=f" (__sqrt_res) : "f" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#if defined __hppa
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrt,dbl %1,%0" : "=fx" (__sqrt_res) : "fx" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#if defined _ARCH_PWR2
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrt %0,%1" : "=f" (__sqrt_res) : "f" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#endif
+
+#ifndef SQRT
+
+/* Tables for initial approximation of the square root. These are
+ indexed with bits 1-8 of the operand for which the square root is
+ calculated, where bit 0 is the most significant non-zero bit. I.e.
+ the most significant one-bit is not used, since that per definition
+ is one. Likewise, the tables don't return the highest bit of the
+ result. That bit must be inserted by or:ing the returned value with
+ 0x100. This way, we get a 9-bit approximation from 8-bit tables! */
+
+/* Table to be used for operands with an even total number of bits.
+ (Exactly as in the decimal system there are similarities between the
+ square root of numbers with the same initial digits and an even
+ difference in the total number of digits. Consider the square root
+ of 1, 10, 100, 1000, ...) */
+static unsigned char even_approx_tab[256] =
+{
+ 0x6a, 0x6a, 0x6b, 0x6c, 0x6c, 0x6d, 0x6e, 0x6e,
+ 0x6f, 0x70, 0x71, 0x71, 0x72, 0x73, 0x73, 0x74,
+ 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x79, 0x79,
+ 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x80, 0x81, 0x81, 0x82, 0x83, 0x83, 0x84,
+ 0x85, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x89,
+ 0x8a, 0x8b, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8f,
+ 0x8f, 0x90, 0x90, 0x91, 0x92, 0x92, 0x93, 0x94,
+ 0x94, 0x95, 0x96, 0x96, 0x97, 0x97, 0x98, 0x99,
+ 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e,
+ 0x9e, 0x9f, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3,
+ 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa7,
+ 0xa8, 0xa9, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xac,
+ 0xad, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1,
+ 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb5, 0xb5, 0xb6,
+ 0xb6, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba,
+ 0xbb, 0xbb, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf,
+ 0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3,
+ 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xc8,
+ 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc,
+ 0xcd, 0xce, 0xce, 0xcf, 0xcf, 0xd0, 0xd0, 0xd1,
+ 0xd1, 0xd2, 0xd3, 0xd3, 0xd4, 0xd4, 0xd5, 0xd5,
+ 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9, 0xda,
+ 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde,
+ 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2,
+ 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6, 0xe6,
+ 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xea, 0xea, 0xeb,
+ 0xeb, 0xec, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef,
+ 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3,
+ 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7,
+ 0xf7, 0xf8, 0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfb,
+ 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff,
+};
+
+/* Table to be used for operands with an odd total number of bits.
+ (Further comments before previous table.) */
+static unsigned char odd_approx_tab[256] =
+{
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03,
+ 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
+ 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f,
+ 0x0f, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12,
+ 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16,
+ 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a,
+ 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d,
+ 0x1e, 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x21,
+ 0x21, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24,
+ 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28,
+ 0x28, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b,
+ 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2f,
+ 0x2f, 0x30, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32,
+ 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x35,
+ 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x39,
+ 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c,
+ 0x3c, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3f, 0x3f,
+ 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42,
+ 0x43, 0x43, 0x43, 0x44, 0x44, 0x45, 0x45, 0x45,
+ 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c,
+ 0x4c, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4f,
+ 0x4f, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52,
+ 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x55,
+ 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58,
+ 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b,
+ 0x5b, 0x5b, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e,
+ 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61,
+ 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63,
+ 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66,
+ 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69,
+};
+#endif
+
+
+mp_size_t
+#if __STDC__
+mpn_sqrtrem (mp_ptr root_ptr, mp_ptr rem_ptr, mp_srcptr op_ptr, mp_size_t op_size)
+#else
+mpn_sqrtrem (root_ptr, rem_ptr, op_ptr, op_size)
+ mp_ptr root_ptr;
+ mp_ptr rem_ptr;
+ mp_srcptr op_ptr;
+ mp_size_t op_size;
+#endif
+{
+ /* R (root result) */
+ mp_ptr rp; /* Pointer to least significant word */
+ mp_size_t rsize; /* The size in words */
+
+ /* T (OP shifted to the left a.k.a. normalized) */
+ mp_ptr tp; /* Pointer to least significant word */
+ mp_size_t tsize; /* The size in words */
+ mp_ptr t_end_ptr; /* Pointer right beyond most sign. word */
+ mp_limb_t t_high0, t_high1; /* The two most significant words */
+
+ /* TT (temporary for numerator/remainder) */
+ mp_ptr ttp; /* Pointer to least significant word */
+
+ /* X (temporary for quotient in main loop) */
+ mp_ptr xp; /* Pointer to least significant word */
+ mp_size_t xsize; /* The size in words */
+
+ unsigned cnt;
+ mp_limb_t initial_approx; /* Initially made approximation */
+ mp_size_t tsizes[BITS_PER_MP_LIMB]; /* Successive calculation precisions */
+ mp_size_t tmp;
+ mp_size_t i;
+
+ mp_limb_t cy_limb;
+ TMP_DECL (marker);
+
+ /* If OP is zero, both results are zero. */
+ if (op_size == 0)
+ return 0;
+
+ count_leading_zeros (cnt, op_ptr[op_size - 1]);
+ tsize = op_size;
+ if ((tsize & 1) != 0)
+ {
+ cnt += BITS_PER_MP_LIMB;
+ tsize++;
+ }
+
+ rsize = tsize / 2;
+ rp = root_ptr;
+
+ TMP_MARK (marker);
+
+ /* Shift OP an even number of bits into T, such that either the most or
+ the second most significant bit is set, and such that the number of
+ words in T becomes even. This way, the number of words in R=sqrt(OP)
+ is exactly half as many as in OP, and the most significant bit of R
+ is set.
+
+ Also, the initial approximation is simplified by this up-shifted OP.
+
+ Finally, the Newtonian iteration which is the main part of this
+ program performs division by R. The fast division routine expects
+ the divisor to be "normalized" in exactly the sense of having the
+ most significant bit set. */
+
+ tp = (mp_ptr) TMP_ALLOC (tsize * BYTES_PER_MP_LIMB);
+
+ if ((cnt & ~1) % BITS_PER_MP_LIMB != 0)
+ t_high0 = mpn_lshift (tp + cnt / BITS_PER_MP_LIMB, op_ptr, op_size,
+ (cnt & ~1) % BITS_PER_MP_LIMB);
+ else
+ MPN_COPY (tp + cnt / BITS_PER_MP_LIMB, op_ptr, op_size);
+
+ if (cnt >= BITS_PER_MP_LIMB)
+ tp[0] = 0;
+
+ t_high0 = tp[tsize - 1];
+ t_high1 = tp[tsize - 2]; /* Never stray. TSIZE is >= 2. */
+
+/* Is there a fast sqrt instruction defined for this machine? */
+#ifdef SQRT
+ {
+ initial_approx = SQRT (t_high0 * 2.0
+ * ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1))
+ + t_high1);
+ /* If t_high0,,t_high1 is big, the result in INITIAL_APPROX might have
+ become incorrect due to overflow in the conversion from double to
+ mp_limb_t above. It will typically be zero in that case, but might be
+ a small number on some machines. The most significant bit of
+ INITIAL_APPROX should be set, so that bit is a good overflow
+ indication. */
+ if ((mp_limb_signed_t) initial_approx >= 0)
+ initial_approx = ~(mp_limb_t)0;
+ }
+#else
+ /* Get a 9 bit approximation from the tables. The tables expect to
+ be indexed with the 8 high bits right below the highest bit.
+ Also, the highest result bit is not returned by the tables, and
+ must be or:ed into the result. The scheme gives 9 bits of start
+ approximation with just 256-entry 8 bit tables. */
+
+ if ((cnt & 1) == 0)
+ {
+ /* The most sign bit of t_high0 is set. */
+ initial_approx = t_high0 >> (BITS_PER_MP_LIMB - 8 - 1);
+ initial_approx &= 0xff;
+ initial_approx = even_approx_tab[initial_approx];
+ }
+ else
+ {
+ /* The most significant bit of T_HIGH0 is unset,
+ the second most significant is set. */
+ initial_approx = t_high0 >> (BITS_PER_MP_LIMB - 8 - 2);
+ initial_approx &= 0xff;
+ initial_approx = odd_approx_tab[initial_approx];
+ }
+ initial_approx |= 0x100;
+ initial_approx <<= BITS_PER_MP_LIMB - 8 - 1;
+
+ /* Perform small precision Newtonian iterations to get a full word
+ approximation. For small operands, these iteration will make the
+ entire job. */
+ if (t_high0 == ~(mp_limb_t)0)
+ initial_approx = t_high0;
+ else
+ {
+ mp_limb_t quot;
+
+ if (t_high0 >= initial_approx)
+ initial_approx = t_high0 + 1;
+
+ /* First get about 18 bits with pure C arithmetics. */
+ quot = t_high0 / (initial_approx >> BITS_PER_MP_LIMB/2) << BITS_PER_MP_LIMB/2;
+ initial_approx = (initial_approx + quot) / 2;
+ initial_approx |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+
+ /* Now get a full word by one (or for > 36 bit machines) several
+ iterations. */
+ for (i = 16; i < BITS_PER_MP_LIMB; i <<= 1)
+ {
+ mp_limb_t ignored_remainder;
+
+ udiv_qrnnd (quot, ignored_remainder,
+ t_high0, t_high1, initial_approx);
+ initial_approx = (initial_approx + quot) / 2;
+ initial_approx |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+#endif
+
+ rp[0] = initial_approx;
+ rsize = 1;
+
+#ifdef DEBUG
+ printf ("\n\nT = ");
+ mpn_dump (tp, tsize);
+#endif
+
+ if (tsize > 2)
+ {
+ /* Determine the successive precisions to use in the iteration. We
+ minimize the precisions, beginning with the highest (i.e. last
+ iteration) to the lowest (i.e. first iteration). */
+
+ xp = (mp_ptr) TMP_ALLOC (tsize * BYTES_PER_MP_LIMB);
+ ttp = (mp_ptr) TMP_ALLOC (tsize * BYTES_PER_MP_LIMB);
+
+ t_end_ptr = tp + tsize;
+
+ tmp = tsize / 2;
+ for (i = 0;; i++)
+ {
+ tsize = (tmp + 1) / 2;
+ if (tmp == tsize)
+ break;
+ tsizes[i] = tsize + tmp;
+ tmp = tsize;
+ }
+
+ /* Main Newton iteration loop. For big arguments, most of the
+ time is spent here. */
+
+ /* It is possible to do a great optimization here. The successive
+ divisors in the mpn_divmod call below has more and more leading
+ words equal to its predecessor. Therefore the beginning of
+ each division will repeat the same work as did the last
+ division. If we could guarantee that the leading words of two
+ consecutive divisors are the same (i.e. in this case, a later
+ divisor has just more digits at the end) it would be a simple
+ matter of just using the old remainder of the last division in
+ a subsequent division, to take care of this optimization. This
+ idea would surely make a difference even for small arguments. */
+
+ /* Loop invariants:
+
+ R <= shiftdown_to_same_size(floor(sqrt(OP))) < R + 1.
+ X - 1 < shiftdown_to_same_size(floor(sqrt(OP))) <= X.
+ R <= shiftdown_to_same_size(X). */
+
+ while (--i >= 0)
+ {
+ mp_limb_t cy;
+#ifdef DEBUG
+ mp_limb_t old_least_sign_r = rp[0];
+ mp_size_t old_rsize = rsize;
+
+ printf ("R = ");
+ mpn_dump (rp, rsize);
+#endif
+ tsize = tsizes[i];
+
+ /* Need to copy the numerator into temporary space, as
+ mpn_divmod overwrites its numerator argument with the
+ remainder (which we currently ignore). */
+ MPN_COPY (ttp, t_end_ptr - tsize, tsize);
+ cy = mpn_divmod (xp, ttp, tsize, rp, rsize);
+ xsize = tsize - rsize;
+
+#ifdef DEBUG
+ printf ("X =%d ", cy);
+ mpn_dump (xp, xsize);
+#endif
+
+ /* Add X and R with the most significant limbs aligned,
+ temporarily ignoring at least one limb at the low end of X. */
+ tmp = xsize - rsize;
+ cy += mpn_add_n (xp + tmp, rp, xp + tmp, rsize);
+
+ /* If T begins with more than 2 x BITS_PER_MP_LIMB of ones, we get
+ intermediate roots that'd need an extra bit. We don't want to
+ handle that since it would make the subsequent divisor
+ non-normalized, so round such roots down to be only ones in the
+ current precision. */
+ if (cy == 2)
+ {
+ mp_size_t j;
+ for (j = xsize; j >= 0; j--)
+ xp[j] = ~(mp_limb_t)0;
+ }
+
+ /* Divide X by 2 and put the result in R. This is the new
+ approximation. Shift in the carry from the addition. */
+ mpn_rshift (rp, xp, xsize, 1);
+ rp[xsize - 1] |= ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1));
+ rsize = xsize;
+#ifdef DEBUG
+ if (old_least_sign_r != rp[rsize - old_rsize])
+ printf (">>>>>>>> %d: %0*lX, %0*lX <<<<<<<<\n",
+ i, 2 * BYTES_PER_MP_LIMB, old_least_sign_r,
+ 2 * BYTES_PER_MP_LIMB, rp[rsize - old_rsize]);
+#endif
+ }
+ }
+
+#ifdef DEBUG
+ printf ("(final) R = ");
+ mpn_dump (rp, rsize);
+#endif
+
+ /* We computed the square root of OP * 2**(2*floor(cnt/2)).
+ This has resulted in R being 2**floor(cnt/2) to large.
+ Shift it down here to fix that. */
+ if (cnt / 2 != 0)
+ {
+ mpn_rshift (rp, rp, rsize, cnt/2);
+ rsize -= rp[rsize - 1] == 0;
+ }
+
+ /* Calculate the remainder. */
+ mpn_mul_n (tp, rp, rp, rsize);
+ tsize = rsize + rsize;
+ tsize -= tp[tsize - 1] == 0;
+ if (op_size < tsize
+ || (op_size == tsize && mpn_cmp (op_ptr, tp, op_size) < 0))
+ {
+ /* R is too large. Decrement it. */
+
+ /* These operations can't overflow. */
+ cy_limb = mpn_sub_n (tp, tp, rp, rsize);
+ cy_limb += mpn_sub_n (tp, tp, rp, rsize);
+ mpn_sub_1 (tp + rsize, tp + rsize, tsize - rsize, cy_limb);
+ mpn_add_1 (tp, tp, tsize, (mp_limb_t) 1);
+
+ mpn_sub_1 (rp, rp, rsize, (mp_limb_t) 1);
+
+#ifdef DEBUG
+ printf ("(adjusted) R = ");
+ mpn_dump (rp, rsize);
+#endif
+ }
+
+ if (rem_ptr != NULL)
+ {
+ cy_limb = mpn_sub (rem_ptr, op_ptr, op_size, tp, tsize);
+ MPN_NORMALIZE (rem_ptr, op_size);
+ TMP_FREE (marker);
+ return op_size;
+ }
+ else
+ {
+ int res;
+ res = op_size != tsize || mpn_cmp (op_ptr, tp, op_size);
+ TMP_FREE (marker);
+ return res;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/generic/sub_n.c b/gnu/lib/libgmp/mpn/generic/sub_n.c
new file mode 100644
index 0000000..9d4b216
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/sub_n.c
@@ -0,0 +1,62 @@
+/* mpn_sub_n -- Subtract two limb vectors of equal, non-zero length.
+
+Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+#if __STDC__
+mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+mpn_sub_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy = (y > x) + cy; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/submul_1.c b/gnu/lib/libgmp/mpn/generic/submul_1.c
new file mode 100644
index 0000000..b144283
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/submul_1.c
@@ -0,0 +1,65 @@
+/* mpn_submul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR
+ by S2_LIMB, subtract the S1_SIZE least significant limbs of the product
+ from the limb vector pointed to by RES_PTR. Return the most significant
+ limb of the product, adjusted for carry-out from the subtraction.
+
+Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_submul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+ register mp_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += (prod_low > x);
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
diff --git a/gnu/lib/libgmp/mpn/generic/udiv_w_sdiv.c b/gnu/lib/libgmp/mpn/generic/udiv_w_sdiv.c
new file mode 100644
index 0000000..d9e71b7
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/generic/udiv_w_sdiv.c
@@ -0,0 +1,125 @@
+/* mpn_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
+ division.
+
+ Contributed by Peter L. Montgomery.
+
+Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb_t
+mpn_udiv_w_sdiv (rp, a1, a0, d)
+ mp_limb_t *rp, a1, a0, d;
+{
+ mp_limb_t q, r;
+ mp_limb_t c0, c1, b1;
+
+ if ((mp_limb_signed_t) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
diff --git a/gnu/lib/libgmp/mpn/mp_bases.c b/gnu/lib/libgmp/mpn/mp_bases.c
new file mode 100644
index 0000000..bbe39b0
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/mp_bases.c
@@ -0,0 +1,549 @@
+/* __mp_bases -- Structure for conversion between internal binary
+ format and strings in base 2..255. The fields are explained in
+ gmp-impl.h.
+
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if BITS_PER_MP_LIMB == 32
+const struct bases __mp_bases[256] =
+{
+ /* 0 */ {0, 0.0, 0, 0},
+ /* 1 */ {0, 1e38, 0, 0},
+ /* 2 */ {32, 1.00000000, 0x1, 0x0},
+ /* 3 */ {20, 0.63092975, 0xcfd41b91, 0x3b563c24},
+ /* 4 */ {16, 0.50000000, 0x2, 0x0},
+ /* 5 */ {13, 0.43067656, 0x48c27395, 0xc25c2684},
+ /* 6 */ {12, 0.38685281, 0x81bf1000, 0xf91bd1b6},
+ /* 7 */ {11, 0.35620719, 0x75db9c97, 0x1607a2cb},
+ /* 8 */ {10, 0.33333333, 0x3, 0x0},
+ /* 9 */ {10, 0.31546488, 0xcfd41b91, 0x3b563c24},
+ /* 10 */ {9, 0.30103000, 0x3b9aca00, 0x12e0be82},
+ /* 11 */ {9, 0.28906483, 0x8c8b6d2b, 0xd24cde04},
+ /* 12 */ {8, 0.27894295, 0x19a10000, 0x3fa39ab5},
+ /* 13 */ {8, 0.27023815, 0x309f1021, 0x50f8ac5f},
+ /* 14 */ {8, 0.26264954, 0x57f6c100, 0x74843b1e},
+ /* 15 */ {8, 0.25595802, 0x98c29b81, 0xad0326c2},
+ /* 16 */ {8, 0.25000000, 0x4, 0x0},
+ /* 17 */ {7, 0.24465054, 0x18754571, 0x4ef0b6bd},
+ /* 18 */ {7, 0.23981247, 0x247dbc80, 0xc0fc48a1},
+ /* 19 */ {7, 0.23540891, 0x3547667b, 0x33838942},
+ /* 20 */ {7, 0.23137821, 0x4c4b4000, 0xad7f29ab},
+ /* 21 */ {7, 0.22767025, 0x6b5a6e1d, 0x313c3d15},
+ /* 22 */ {7, 0.22424382, 0x94ace180, 0xb8cca9e0},
+ /* 23 */ {7, 0.22106473, 0xcaf18367, 0x42ed6de9},
+ /* 24 */ {6, 0.21810429, 0xb640000, 0x67980e0b},
+ /* 25 */ {6, 0.21533828, 0xe8d4a51, 0x19799812},
+ /* 26 */ {6, 0.21274605, 0x1269ae40, 0xbce85396},
+ /* 27 */ {6, 0.21030992, 0x17179149, 0x62c103a9},
+ /* 28 */ {6, 0.20801460, 0x1cb91000, 0x1d353d43},
+ /* 29 */ {6, 0.20584683, 0x23744899, 0xce1decea},
+ /* 30 */ {6, 0.20379505, 0x2b73a840, 0x790fc511},
+ /* 31 */ {6, 0.20184909, 0x34e63b41, 0x35b865a0},
+ /* 32 */ {6, 0.20000000, 0x5, 0x0},
+ /* 33 */ {6, 0.19823986, 0x4cfa3cc1, 0xa9aed1b3},
+ /* 34 */ {6, 0.19656163, 0x5c13d840, 0x63dfc229},
+ /* 35 */ {6, 0.19495902, 0x6d91b519, 0x2b0fee30},
+ /* 36 */ {6, 0.19342640, 0x81bf1000, 0xf91bd1b6},
+ /* 37 */ {6, 0.19195872, 0x98ede0c9, 0xac89c3a9},
+ /* 38 */ {6, 0.19055141, 0xb3773e40, 0x6d2c32fe},
+ /* 39 */ {6, 0.18920036, 0xd1bbc4d1, 0x387907c9},
+ /* 40 */ {6, 0.18790182, 0xf4240000, 0xc6f7a0b},
+ /* 41 */ {5, 0.18665241, 0x6e7d349, 0x28928154},
+ /* 42 */ {5, 0.18544902, 0x7ca30a0, 0x6e8629d},
+ /* 43 */ {5, 0.18428883, 0x8c32bbb, 0xd373dca0},
+ /* 44 */ {5, 0.18316925, 0x9d46c00, 0xa0b17895},
+ /* 45 */ {5, 0.18208790, 0xaffacfd, 0x746811a5},
+ /* 46 */ {5, 0.18104260, 0xc46bee0, 0x4da6500f},
+ /* 47 */ {5, 0.18003133, 0xdab86ef, 0x2ba23582},
+ /* 48 */ {5, 0.17905223, 0xf300000, 0xdb20a88},
+ /* 49 */ {5, 0.17810359, 0x10d63af1, 0xe68d5ce4},
+ /* 50 */ {5, 0.17718382, 0x12a05f20, 0xb7cdfd9d},
+ /* 51 */ {5, 0.17629143, 0x1490aae3, 0x8e583933},
+ /* 52 */ {5, 0.17542506, 0x16a97400, 0x697cc3ea},
+ /* 53 */ {5, 0.17458343, 0x18ed2825, 0x48a5ca6c},
+ /* 54 */ {5, 0.17376534, 0x1b5e4d60, 0x2b52db16},
+ /* 55 */ {5, 0.17296969, 0x1dff8297, 0x111586a6},
+ /* 56 */ {5, 0.17219543, 0x20d38000, 0xf31d2b36},
+ /* 57 */ {5, 0.17144160, 0x23dd1799, 0xc8d76d19},
+ /* 58 */ {5, 0.17070728, 0x271f35a0, 0xa2cb1eb4},
+ /* 59 */ {5, 0.16999162, 0x2a9ce10b, 0x807c3ec3},
+ /* 60 */ {5, 0.16929381, 0x2e593c00, 0x617ec8bf},
+ /* 61 */ {5, 0.16861310, 0x3257844d, 0x45746cbe},
+ /* 62 */ {5, 0.16794878, 0x369b13e0, 0x2c0aa273},
+ /* 63 */ {5, 0.16730018, 0x3b27613f, 0x14f90805},
+ /* 64 */ {5, 0.16666667, 0x6, 0x0},
+ /* 65 */ {5, 0.16604765, 0x4528a141, 0xd9cf0829},
+ /* 66 */ {5, 0.16544255, 0x4aa51420, 0xb6fc4841},
+ /* 67 */ {5, 0.16485086, 0x50794633, 0x973054cb},
+ /* 68 */ {5, 0.16427205, 0x56a94400, 0x7a1dbe4b},
+ /* 69 */ {5, 0.16370566, 0x5d393975, 0x5f7fcd7f},
+ /* 70 */ {5, 0.16315122, 0x642d7260, 0x47196c84},
+ /* 71 */ {5, 0.16260831, 0x6b8a5ae7, 0x30b43635},
+ /* 72 */ {5, 0.16207652, 0x73548000, 0x1c1fa5f6},
+ /* 73 */ {5, 0.16155547, 0x7b908fe9, 0x930634a},
+ /* 74 */ {5, 0.16104477, 0x84435aa0, 0xef7f4a3c},
+ /* 75 */ {5, 0.16054409, 0x8d71d25b, 0xcf5552d2},
+ /* 76 */ {5, 0.16005307, 0x97210c00, 0xb1a47c8e},
+ /* 77 */ {5, 0.15957142, 0xa1563f9d, 0x9634b43e},
+ /* 78 */ {5, 0.15909881, 0xac16c8e0, 0x7cd3817d},
+ /* 79 */ {5, 0.15863496, 0xb768278f, 0x65536761},
+ /* 80 */ {5, 0.15817959, 0xc3500000, 0x4f8b588e},
+ /* 81 */ {5, 0.15773244, 0xcfd41b91, 0x3b563c24},
+ /* 82 */ {5, 0.15729325, 0xdcfa6920, 0x28928154},
+ /* 83 */ {5, 0.15686177, 0xeac8fd83, 0x1721bfb0},
+ /* 84 */ {5, 0.15643779, 0xf9461400, 0x6e8629d},
+ /* 85 */ {4, 0.15602107, 0x31c84b1, 0x491cc17c},
+ /* 86 */ {4, 0.15561139, 0x342ab10, 0x3a11d83b},
+ /* 87 */ {4, 0.15520856, 0x36a2c21, 0x2be074cd},
+ /* 88 */ {4, 0.15481238, 0x3931000, 0x1e7a02e7},
+ /* 89 */ {4, 0.15442266, 0x3bd5ee1, 0x11d10edd},
+ /* 90 */ {4, 0.15403922, 0x3e92110, 0x5d92c68},
+ /* 91 */ {4, 0.15366189, 0x4165ef1, 0xf50dbfb2},
+ /* 92 */ {4, 0.15329049, 0x4452100, 0xdf9f1316},
+ /* 93 */ {4, 0.15292487, 0x4756fd1, 0xcb52a684},
+ /* 94 */ {4, 0.15256487, 0x4a75410, 0xb8163e97},
+ /* 95 */ {4, 0.15221035, 0x4dad681, 0xa5d8f269},
+ /* 96 */ {4, 0.15186115, 0x5100000, 0x948b0fcd},
+ /* 97 */ {4, 0.15151715, 0x546d981, 0x841e0215},
+ /* 98 */ {4, 0.15117821, 0x57f6c10, 0x74843b1e},
+ /* 99 */ {4, 0.15084420, 0x5b9c0d1, 0x65b11e6e},
+ /* 100 */ {4, 0.15051500, 0x5f5e100, 0x5798ee23},
+ /* 101 */ {4, 0.15019048, 0x633d5f1, 0x4a30b99b},
+ /* 102 */ {4, 0.14987054, 0x673a910, 0x3d6e4d94},
+ /* 103 */ {4, 0.14955506, 0x6b563e1, 0x314825b0},
+ /* 104 */ {4, 0.14924394, 0x6f91000, 0x25b55f2e},
+ /* 105 */ {4, 0.14893706, 0x73eb721, 0x1aadaccb},
+ /* 106 */ {4, 0.14863434, 0x7866310, 0x10294ba2},
+ /* 107 */ {4, 0.14833567, 0x7d01db1, 0x620f8f6},
+ /* 108 */ {4, 0.14804096, 0x81bf100, 0xf91bd1b6},
+ /* 109 */ {4, 0.14775011, 0x869e711, 0xe6d37b2a},
+ /* 110 */ {4, 0.14746305, 0x8ba0a10, 0xd55cff6e},
+ /* 111 */ {4, 0.14717969, 0x90c6441, 0xc4ad2db2},
+ /* 112 */ {4, 0.14689994, 0x9610000, 0xb4b985cf},
+ /* 113 */ {4, 0.14662372, 0x9b7e7c1, 0xa5782bef},
+ /* 114 */ {4, 0.14635096, 0xa112610, 0x96dfdd2a},
+ /* 115 */ {4, 0.14608158, 0xa6cc591, 0x88e7e509},
+ /* 116 */ {4, 0.14581551, 0xacad100, 0x7b8813d3},
+ /* 117 */ {4, 0.14555268, 0xb2b5331, 0x6eb8b595},
+ /* 118 */ {4, 0.14529302, 0xb8e5710, 0x627289db},
+ /* 119 */ {4, 0.14503647, 0xbf3e7a1, 0x56aebc07},
+ /* 120 */ {4, 0.14478295, 0xc5c1000, 0x4b66dc33},
+ /* 121 */ {4, 0.14453241, 0xcc6db61, 0x4094d8a3},
+ /* 122 */ {4, 0.14428479, 0xd345510, 0x3632f7a5},
+ /* 123 */ {4, 0.14404003, 0xda48871, 0x2c3bd1f0},
+ /* 124 */ {4, 0.14379807, 0xe178100, 0x22aa4d5f},
+ /* 125 */ {4, 0.14355885, 0xe8d4a51, 0x19799812},
+ /* 126 */ {4, 0.14332233, 0xf05f010, 0x10a523e5},
+ /* 127 */ {4, 0.14308844, 0xf817e01, 0x828a237},
+ /* 128 */ {4, 0.14285714, 0x7, 0x0},
+ /* 129 */ {4, 0.14262838, 0x10818201, 0xf04ec452},
+ /* 130 */ {4, 0.14240211, 0x11061010, 0xe136444a},
+ /* 131 */ {4, 0.14217828, 0x118db651, 0xd2af9589},
+ /* 132 */ {4, 0.14195685, 0x12188100, 0xc4b42a83},
+ /* 133 */ {4, 0.14173777, 0x12a67c71, 0xb73dccf5},
+ /* 134 */ {4, 0.14152100, 0x1337b510, 0xaa4698c5},
+ /* 135 */ {4, 0.14130649, 0x13cc3761, 0x9dc8f729},
+ /* 136 */ {4, 0.14109421, 0x14641000, 0x91bf9a30},
+ /* 137 */ {4, 0.14088412, 0x14ff4ba1, 0x86257887},
+ /* 138 */ {4, 0.14067617, 0x159df710, 0x7af5c98c},
+ /* 139 */ {4, 0.14047033, 0x16401f31, 0x702c01a0},
+ /* 140 */ {4, 0.14026656, 0x16e5d100, 0x65c3ceb1},
+ /* 141 */ {4, 0.14006482, 0x178f1991, 0x5bb91502},
+ /* 142 */ {4, 0.13986509, 0x183c0610, 0x5207ec23},
+ /* 143 */ {4, 0.13966731, 0x18eca3c1, 0x48ac9c19},
+ /* 144 */ {4, 0.13947147, 0x19a10000, 0x3fa39ab5},
+ /* 145 */ {4, 0.13927753, 0x1a592841, 0x36e98912},
+ /* 146 */ {4, 0.13908545, 0x1b152a10, 0x2e7b3140},
+ /* 147 */ {4, 0.13889521, 0x1bd51311, 0x2655840b},
+ /* 148 */ {4, 0.13870677, 0x1c98f100, 0x1e7596ea},
+ /* 149 */ {4, 0.13852011, 0x1d60d1b1, 0x16d8a20d},
+ /* 150 */ {4, 0.13833519, 0x1e2cc310, 0xf7bfe87},
+ /* 151 */ {4, 0.13815199, 0x1efcd321, 0x85d2492},
+ /* 152 */ {4, 0.13797047, 0x1fd11000, 0x179a9f4},
+ /* 153 */ {4, 0.13779062, 0x20a987e1, 0xf59e80eb},
+ /* 154 */ {4, 0.13761241, 0x21864910, 0xe8b768db},
+ /* 155 */ {4, 0.13743580, 0x226761f1, 0xdc39d6d5},
+ /* 156 */ {4, 0.13726078, 0x234ce100, 0xd021c5d1},
+ /* 157 */ {4, 0.13708732, 0x2436d4d1, 0xc46b5e37},
+ /* 158 */ {4, 0.13691539, 0x25254c10, 0xb912f39c},
+ /* 159 */ {4, 0.13674498, 0x26185581, 0xae150294},
+ /* 160 */ {4, 0.13657605, 0x27100000, 0xa36e2eb1},
+ /* 161 */ {4, 0.13640859, 0x280c5a81, 0x991b4094},
+ /* 162 */ {4, 0.13624257, 0x290d7410, 0x8f19241e},
+ /* 163 */ {4, 0.13607797, 0x2a135bd1, 0x8564e6b7},
+ /* 164 */ {4, 0.13591477, 0x2b1e2100, 0x7bfbb5b4},
+ /* 165 */ {4, 0.13575295, 0x2c2dd2f1, 0x72dadcc8},
+ /* 166 */ {4, 0.13559250, 0x2d428110, 0x69ffc498},
+ /* 167 */ {4, 0.13543338, 0x2e5c3ae1, 0x6167f154},
+ /* 168 */ {4, 0.13527558, 0x2f7b1000, 0x5911016e},
+ /* 169 */ {4, 0.13511908, 0x309f1021, 0x50f8ac5f},
+ /* 170 */ {4, 0.13496386, 0x31c84b10, 0x491cc17c},
+ /* 171 */ {4, 0.13480991, 0x32f6d0b1, 0x417b26d8},
+ /* 172 */ {4, 0.13465720, 0x342ab100, 0x3a11d83b},
+ /* 173 */ {4, 0.13450572, 0x3563fc11, 0x32dee622},
+ /* 174 */ {4, 0.13435545, 0x36a2c210, 0x2be074cd},
+ /* 175 */ {4, 0.13420637, 0x37e71341, 0x2514bb58},
+ /* 176 */ {4, 0.13405847, 0x39310000, 0x1e7a02e7},
+ /* 177 */ {4, 0.13391173, 0x3a8098c1, 0x180ea5d0},
+ /* 178 */ {4, 0.13376614, 0x3bd5ee10, 0x11d10edd},
+ /* 179 */ {4, 0.13362168, 0x3d311091, 0xbbfb88e},
+ /* 180 */ {4, 0.13347832, 0x3e921100, 0x5d92c68},
+ /* 181 */ {4, 0.13333607, 0x3ff90031, 0x1c024c},
+ /* 182 */ {4, 0.13319491, 0x4165ef10, 0xf50dbfb2},
+ /* 183 */ {4, 0.13305481, 0x42d8eea1, 0xea30efa3},
+ /* 184 */ {4, 0.13291577, 0x44521000, 0xdf9f1316},
+ /* 185 */ {4, 0.13277777, 0x45d16461, 0xd555c0c9},
+ /* 186 */ {4, 0.13264079, 0x4756fd10, 0xcb52a684},
+ /* 187 */ {4, 0.13250483, 0x48e2eb71, 0xc193881f},
+ /* 188 */ {4, 0.13236988, 0x4a754100, 0xb8163e97},
+ /* 189 */ {4, 0.13223591, 0x4c0e0f51, 0xaed8b724},
+ /* 190 */ {4, 0.13210292, 0x4dad6810, 0xa5d8f269},
+ /* 191 */ {4, 0.13197089, 0x4f535d01, 0x9d15039d},
+ /* 192 */ {4, 0.13183981, 0x51000000, 0x948b0fcd},
+ /* 193 */ {4, 0.13170967, 0x52b36301, 0x8c394d1d},
+ /* 194 */ {4, 0.13158046, 0x546d9810, 0x841e0215},
+ /* 195 */ {4, 0.13145216, 0x562eb151, 0x7c3784f8},
+ /* 196 */ {4, 0.13132477, 0x57f6c100, 0x74843b1e},
+ /* 197 */ {4, 0.13119827, 0x59c5d971, 0x6d02985d},
+ /* 198 */ {4, 0.13107265, 0x5b9c0d10, 0x65b11e6e},
+ /* 199 */ {4, 0.13094791, 0x5d796e61, 0x5e8e5c64},
+ /* 200 */ {4, 0.13082402, 0x5f5e1000, 0x5798ee23},
+ /* 201 */ {4, 0.13070099, 0x614a04a1, 0x50cf7bde},
+ /* 202 */ {4, 0.13057879, 0x633d5f10, 0x4a30b99b},
+ /* 203 */ {4, 0.13045743, 0x65383231, 0x43bb66bd},
+ /* 204 */ {4, 0.13033688, 0x673a9100, 0x3d6e4d94},
+ /* 205 */ {4, 0.13021715, 0x69448e91, 0x374842ee},
+ /* 206 */ {4, 0.13009822, 0x6b563e10, 0x314825b0},
+ /* 207 */ {4, 0.12998007, 0x6d6fb2c1, 0x2b6cde75},
+ /* 208 */ {4, 0.12986271, 0x6f910000, 0x25b55f2e},
+ /* 209 */ {4, 0.12974613, 0x71ba3941, 0x2020a2c5},
+ /* 210 */ {4, 0.12963031, 0x73eb7210, 0x1aadaccb},
+ /* 211 */ {4, 0.12951524, 0x7624be11, 0x155b891f},
+ /* 212 */ {4, 0.12940092, 0x78663100, 0x10294ba2},
+ /* 213 */ {4, 0.12928734, 0x7aafdeb1, 0xb160fe9},
+ /* 214 */ {4, 0.12917448, 0x7d01db10, 0x620f8f6},
+ /* 215 */ {4, 0.12906235, 0x7f5c3a21, 0x14930ef},
+ /* 216 */ {4, 0.12895094, 0x81bf1000, 0xf91bd1b6},
+ /* 217 */ {4, 0.12884022, 0x842a70e1, 0xefdcb0c7},
+ /* 218 */ {4, 0.12873021, 0x869e7110, 0xe6d37b2a},
+ /* 219 */ {4, 0.12862089, 0x891b24f1, 0xddfeb94a},
+ /* 220 */ {4, 0.12851224, 0x8ba0a100, 0xd55cff6e},
+ /* 221 */ {4, 0.12840428, 0x8e2ef9d1, 0xcceced50},
+ /* 222 */ {4, 0.12829698, 0x90c64410, 0xc4ad2db2},
+ /* 223 */ {4, 0.12819034, 0x93669481, 0xbc9c75f9},
+ /* 224 */ {4, 0.12808435, 0x96100000, 0xb4b985cf},
+ /* 225 */ {4, 0.12797901, 0x98c29b81, 0xad0326c2},
+ /* 226 */ {4, 0.12787431, 0x9b7e7c10, 0xa5782bef},
+ /* 227 */ {4, 0.12777024, 0x9e43b6d1, 0x9e1771a9},
+ /* 228 */ {4, 0.12766680, 0xa1126100, 0x96dfdd2a},
+ /* 229 */ {4, 0.12756398, 0xa3ea8ff1, 0x8fd05c41},
+ /* 230 */ {4, 0.12746176, 0xa6cc5910, 0x88e7e509},
+ /* 231 */ {4, 0.12736016, 0xa9b7d1e1, 0x8225759d},
+ /* 232 */ {4, 0.12725915, 0xacad1000, 0x7b8813d3},
+ /* 233 */ {4, 0.12715874, 0xafac2921, 0x750eccf9},
+ /* 234 */ {4, 0.12705891, 0xb2b53310, 0x6eb8b595},
+ /* 235 */ {4, 0.12695967, 0xb5c843b1, 0x6884e923},
+ /* 236 */ {4, 0.12686100, 0xb8e57100, 0x627289db},
+ /* 237 */ {4, 0.12676290, 0xbc0cd111, 0x5c80c07b},
+ /* 238 */ {4, 0.12666537, 0xbf3e7a10, 0x56aebc07},
+ /* 239 */ {4, 0.12656839, 0xc27a8241, 0x50fbb19b},
+ /* 240 */ {4, 0.12647197, 0xc5c10000, 0x4b66dc33},
+ /* 241 */ {4, 0.12637609, 0xc91209c1, 0x45ef7c7c},
+ /* 242 */ {4, 0.12628075, 0xcc6db610, 0x4094d8a3},
+ /* 243 */ {4, 0.12618595, 0xcfd41b91, 0x3b563c24},
+ /* 244 */ {4, 0.12609168, 0xd3455100, 0x3632f7a5},
+ /* 245 */ {4, 0.12599794, 0xd6c16d31, 0x312a60c3},
+ /* 246 */ {4, 0.12590471, 0xda488710, 0x2c3bd1f0},
+ /* 247 */ {4, 0.12581200, 0xdddab5a1, 0x2766aa45},
+ /* 248 */ {4, 0.12571980, 0xe1781000, 0x22aa4d5f},
+ /* 249 */ {4, 0.12562811, 0xe520ad61, 0x1e06233c},
+ /* 250 */ {4, 0.12553692, 0xe8d4a510, 0x19799812},
+ /* 251 */ {4, 0.12544622, 0xec940e71, 0x15041c33},
+ /* 252 */ {4, 0.12535601, 0xf05f0100, 0x10a523e5},
+ /* 253 */ {4, 0.12526629, 0xf4359451, 0xc5c2749},
+ /* 254 */ {4, 0.12517705, 0xf817e010, 0x828a237},
+ /* 255 */ {4, 0.12508829, 0xfc05fc01, 0x40a1423},
+};
+#endif
+#if BITS_PER_MP_LIMB == 64
+const struct bases __mp_bases[256] =
+{
+ /* 0 */ {0, 0.0, 0, 0},
+ /* 1 */ {0, 1e38, 0, 0},
+ /* 2 */ {64, 1.00000000, 0x1, 0x0},
+ /* 3 */ {40, 0.63092975, 0xa8b8b452291fe821L, 0x846d550e37b5063dL},
+ /* 4 */ {32, 0.50000000, 0x2L, 0x0L},
+ /* 5 */ {27, 0.43067656, 0x6765c793fa10079dL, 0x3ce9a36f23c0fc90L},
+ /* 6 */ {24, 0.38685281, 0x41c21cb8e1000000L, 0xf24f62335024a295L},
+ /* 7 */ {22, 0.35620719, 0x3642798750226111L, 0x2df495ccaa57147bL},
+ /* 8 */ {21, 0.33333333, 0x3L, 0x0L},
+ /* 9 */ {20, 0.31546488, 0xa8b8b452291fe821L, 0x846d550e37b5063dL},
+ /* 10 */ {19, 0.30103000, 0x8ac7230489e80000L, 0xd83c94fb6d2ac34aL},
+ /* 11 */ {18, 0.28906483, 0x4d28cb56c33fa539L, 0xa8adf7ae45e7577bL},
+ /* 12 */ {17, 0.27894295, 0x1eca170c00000000L, 0xa10c2bec5da8f8fL},
+ /* 13 */ {17, 0.27023815, 0x780c7372621bd74dL, 0x10f4becafe412ec3L},
+ /* 14 */ {16, 0.26264954, 0x1e39a5057d810000L, 0xf08480f672b4e86L},
+ /* 15 */ {16, 0.25595802, 0x5b27ac993df97701L, 0x6779c7f90dc42f48L},
+ /* 16 */ {16, 0.25000000, 0x4L, 0x0L},
+ /* 17 */ {15, 0.24465054, 0x27b95e997e21d9f1L, 0x9c71e11bab279323L},
+ /* 18 */ {15, 0.23981247, 0x5da0e1e53c5c8000L, 0x5dfaa697ec6f6a1cL},
+ /* 19 */ {15, 0.23540891, 0xd2ae3299c1c4aedbL, 0x3711783f6be7e9ecL},
+ /* 20 */ {14, 0.23137821, 0x16bcc41e90000000L, 0x6849b86a12b9b01eL},
+ /* 21 */ {14, 0.22767025, 0x2d04b7fdd9c0ef49L, 0x6bf097ba5ca5e239L},
+ /* 22 */ {14, 0.22424382, 0x5658597bcaa24000L, 0x7b8015c8d7af8f08L},
+ /* 23 */ {14, 0.22106473, 0xa0e2073737609371L, 0x975a24b3a3151b38L},
+ /* 24 */ {13, 0.21810429, 0xc29e98000000000L, 0x50bd367972689db1L},
+ /* 25 */ {13, 0.21533828, 0x14adf4b7320334b9L, 0x8c240c4aecb13bb5L},
+ /* 26 */ {13, 0.21274605, 0x226ed36478bfa000L, 0xdbd2e56854e118c9L},
+ /* 27 */ {13, 0.21030992, 0x383d9170b85ff80bL, 0x2351ffcaa9c7c4aeL},
+ /* 28 */ {13, 0.20801460, 0x5a3c23e39c000000L, 0x6b24188ca33b0636L},
+ /* 29 */ {13, 0.20584683, 0x8e65137388122bcdL, 0xcc3dceaf2b8ba99dL},
+ /* 30 */ {13, 0.20379505, 0xdd41bb36d259e000L, 0x2832e835c6c7d6b6L},
+ /* 31 */ {12, 0.20184909, 0xaee5720ee830681L, 0x76b6aa272e1873c5L},
+ /* 32 */ {12, 0.20000000, 0x5L, 0x0L},
+ /* 33 */ {12, 0.19823986, 0x172588ad4f5f0981L, 0x61eaf5d402c7bf4fL},
+ /* 34 */ {12, 0.19656163, 0x211e44f7d02c1000L, 0xeeb658123ffb27ecL},
+ /* 35 */ {12, 0.19495902, 0x2ee56725f06e5c71L, 0x5d5e3762e6fdf509L},
+ /* 36 */ {12, 0.19342640, 0x41c21cb8e1000000L, 0xf24f62335024a295L},
+ /* 37 */ {12, 0.19195872, 0x5b5b57f8a98a5dd1L, 0x66ae7831762efb6fL},
+ /* 38 */ {12, 0.19055141, 0x7dcff8986ea31000L, 0x47388865a00f544L},
+ /* 39 */ {12, 0.18920036, 0xabd4211662a6b2a1L, 0x7d673c33a123b54cL},
+ /* 40 */ {12, 0.18790182, 0xe8d4a51000000000L, 0x19799812dea11197L},
+ /* 41 */ {11, 0.18665241, 0x7a32956ad081b79L, 0xc27e62e0686feaeL},
+ /* 42 */ {11, 0.18544902, 0x9f49aaff0e86800L, 0x9b6e7507064ce7c7L},
+ /* 43 */ {11, 0.18428883, 0xce583bb812d37b3L, 0x3d9ac2bf66cfed94L},
+ /* 44 */ {11, 0.18316925, 0x109b79a654c00000L, 0xed46bc50ce59712aL},
+ /* 45 */ {11, 0.18208790, 0x1543beff214c8b95L, 0x813d97e2c89b8d46L},
+ /* 46 */ {11, 0.18104260, 0x1b149a79459a3800L, 0x2e81751956af8083L},
+ /* 47 */ {11, 0.18003133, 0x224edfb5434a830fL, 0xdd8e0a95e30c0988L},
+ /* 48 */ {11, 0.17905223, 0x2b3fb00000000000L, 0x7ad4dd48a0b5b167L},
+ /* 49 */ {11, 0.17810359, 0x3642798750226111L, 0x2df495ccaa57147bL},
+ /* 50 */ {11, 0.17718382, 0x43c33c1937564800L, 0xe392010175ee5962L},
+ /* 51 */ {11, 0.17629143, 0x54411b2441c3cd8bL, 0x84eaf11b2fe7738eL},
+ /* 52 */ {11, 0.17542506, 0x6851455acd400000L, 0x3a1e3971e008995dL},
+ /* 53 */ {11, 0.17458343, 0x80a23b117c8feb6dL, 0xfd7a462344ffce25L},
+ /* 54 */ {11, 0.17376534, 0x9dff7d32d5dc1800L, 0x9eca40b40ebcef8aL},
+ /* 55 */ {11, 0.17296969, 0xc155af6faeffe6a7L, 0x52fa161a4a48e43dL},
+ /* 56 */ {11, 0.17219543, 0xebb7392e00000000L, 0x1607a2cbacf930c1L},
+ /* 57 */ {10, 0.17144160, 0x50633659656d971L, 0x97a014f8e3be55f1L},
+ /* 58 */ {10, 0.17070728, 0x5fa8624c7fba400L, 0x568df8b76cbf212cL},
+ /* 59 */ {10, 0.16999162, 0x717d9faa73c5679L, 0x20ba7c4b4e6ef492L},
+ /* 60 */ {10, 0.16929381, 0x86430aac6100000L, 0xe81ee46b9ef492f5L},
+ /* 61 */ {10, 0.16861310, 0x9e64d9944b57f29L, 0x9dc0d10d51940416L},
+ /* 62 */ {10, 0.16794878, 0xba5ca5392cb0400L, 0x5fa8ed2f450272a5L},
+ /* 63 */ {10, 0.16730018, 0xdab2ce1d022cd81L, 0x2ba9eb8c5e04e641L},
+ /* 64 */ {10, 0.16666667, 0x6L, 0x0L},
+ /* 65 */ {10, 0.16604765, 0x12aeed5fd3e2d281L, 0xb67759cc00287bf1L},
+ /* 66 */ {10, 0.16544255, 0x15c3da1572d50400L, 0x78621feeb7f4ed33L},
+ /* 67 */ {10, 0.16485086, 0x194c05534f75ee29L, 0x43d55b5f72943bc0L},
+ /* 68 */ {10, 0.16427205, 0x1d56299ada100000L, 0x173decb64d1d4409L},
+ /* 69 */ {10, 0.16370566, 0x21f2a089a4ff4f79L, 0xe29fb54fd6b6074fL},
+ /* 70 */ {10, 0.16315122, 0x2733896c68d9a400L, 0xa1f1f5c210d54e62L},
+ /* 71 */ {10, 0.16260831, 0x2d2cf2c33b533c71L, 0x6aac7f9bfafd57b2L},
+ /* 72 */ {10, 0.16207652, 0x33f506e440000000L, 0x3b563c2478b72ee2L},
+ /* 73 */ {10, 0.16155547, 0x3ba43bec1d062211L, 0x12b536b574e92d1bL},
+ /* 74 */ {10, 0.16104477, 0x4455872d8fd4e400L, 0xdf86c03020404fa5L},
+ /* 75 */ {10, 0.16054409, 0x4e2694539f2f6c59L, 0xa34adf02234eea8eL},
+ /* 76 */ {10, 0.16005307, 0x5938006c18900000L, 0x6f46eb8574eb59ddL},
+ /* 77 */ {10, 0.15957142, 0x65ad9912474aa649L, 0x42459b481df47cecL},
+ /* 78 */ {10, 0.15909881, 0x73ae9ff4241ec400L, 0x1b424b95d80ca505L},
+ /* 79 */ {10, 0.15863496, 0x836612ee9c4ce1e1L, 0xf2c1b982203a0dacL},
+ /* 80 */ {10, 0.15817959, 0x9502f90000000000L, 0xb7cdfd9d7bdbab7dL},
+ /* 81 */ {10, 0.15773244, 0xa8b8b452291fe821L, 0x846d550e37b5063dL},
+ /* 82 */ {10, 0.15729325, 0xbebf59a07dab4400L, 0x57931eeaf85cf64fL},
+ /* 83 */ {10, 0.15686177, 0xd7540d4093bc3109L, 0x305a944507c82f47L},
+ /* 84 */ {10, 0.15643779, 0xf2b96616f1900000L, 0xe007ccc9c22781aL},
+ /* 85 */ {9, 0.15602107, 0x336de62af2bca35L, 0x3e92c42e000eeed4L},
+ /* 86 */ {9, 0.15561139, 0x39235ec33d49600L, 0x1ebe59130db2795eL},
+ /* 87 */ {9, 0.15520856, 0x3f674e539585a17L, 0x268859e90f51b89L},
+ /* 88 */ {9, 0.15481238, 0x4645b6958000000L, 0xd24cde0463108cfaL},
+ /* 89 */ {9, 0.15442266, 0x4dcb74afbc49c19L, 0xa536009f37adc383L},
+ /* 90 */ {9, 0.15403922, 0x56064e1d18d9a00L, 0x7cea06ce1c9ace10L},
+ /* 91 */ {9, 0.15366189, 0x5f04fe2cd8a39fbL, 0x58db032e72e8ba43L},
+ /* 92 */ {9, 0.15329049, 0x68d74421f5c0000L, 0x388cc17cae105447L},
+ /* 93 */ {9, 0.15292487, 0x738df1f6ab4827dL, 0x1b92672857620ce0L},
+ /* 94 */ {9, 0.15256487, 0x7f3afbc9cfb5e00L, 0x18c6a9575c2ade4L},
+ /* 95 */ {9, 0.15221035, 0x8bf187fba88f35fL, 0xd44da7da8e44b24fL},
+ /* 96 */ {9, 0.15186115, 0x99c600000000000L, 0xaa2f78f1b4cc6794L},
+ /* 97 */ {9, 0.15151715, 0xa8ce21eb6531361L, 0x843c067d091ee4ccL},
+ /* 98 */ {9, 0.15117821, 0xb92112c1a0b6200L, 0x62005e1e913356e3L},
+ /* 99 */ {9, 0.15084420, 0xcad7718b8747c43L, 0x4316eed01dedd518L},
+ /* 100 */ {9, 0.15051500, 0xde0b6b3a7640000L, 0x2725dd1d243aba0eL},
+ /* 101 */ {9, 0.15019048, 0xf2d8cf5fe6d74c5L, 0xddd9057c24cb54fL},
+ /* 102 */ {9, 0.14987054, 0x1095d25bfa712600L, 0xedeee175a736d2a1L},
+ /* 103 */ {9, 0.14955506, 0x121b7c4c3698faa7L, 0xc4699f3df8b6b328L},
+ /* 104 */ {9, 0.14924394, 0x13c09e8d68000000L, 0x9ebbe7d859cb5a7cL},
+ /* 105 */ {9, 0.14893706, 0x15876ccb0b709ca9L, 0x7c828b9887eb2179L},
+ /* 106 */ {9, 0.14863434, 0x17723c2976da2a00L, 0x5d652ab99001adcfL},
+ /* 107 */ {9, 0.14833567, 0x198384e9c259048bL, 0x4114f1754e5d7b32L},
+ /* 108 */ {9, 0.14804096, 0x1bbde41dfeec0000L, 0x274b7c902f7e0188L},
+ /* 109 */ {9, 0.14775011, 0x1e241d6e3337910dL, 0xfc9e0fbb32e210cL},
+ /* 110 */ {9, 0.14746305, 0x20b91cee9901ee00L, 0xf4afa3e594f8ea1fL},
+ /* 111 */ {9, 0.14717969, 0x237ff9079863dfefL, 0xcd85c32e9e4437b0L},
+ /* 112 */ {9, 0.14689994, 0x267bf47000000000L, 0xa9bbb147e0dd92a8L},
+ /* 113 */ {9, 0.14662372, 0x29b08039fbeda7f1L, 0x8900447b70e8eb82L},
+ /* 114 */ {9, 0.14635096, 0x2d213df34f65f200L, 0x6b0a92adaad5848aL},
+ /* 115 */ {9, 0.14608158, 0x30d201d957a7c2d3L, 0x4f990ad8740f0ee5L},
+ /* 116 */ {9, 0.14581551, 0x34c6d52160f40000L, 0x3670a9663a8d3610L},
+ /* 117 */ {9, 0.14555268, 0x3903f855d8f4c755L, 0x1f5c44188057be3cL},
+ /* 118 */ {9, 0.14529302, 0x3d8de5c8ec59b600L, 0xa2bea956c4e4977L},
+ /* 119 */ {9, 0.14503647, 0x4269541d1ff01337L, 0xed68b23033c3637eL},
+ /* 120 */ {9, 0.14478295, 0x479b38e478000000L, 0xc99cf624e50549c5L},
+ /* 121 */ {9, 0.14453241, 0x4d28cb56c33fa539L, 0xa8adf7ae45e7577bL},
+ /* 122 */ {9, 0.14428479, 0x5317871fa13aba00L, 0x8a5bc740b1c113e5L},
+ /* 123 */ {9, 0.14404003, 0x596d2f44de9fa71bL, 0x6e6c7efb81cfbb9bL},
+ /* 124 */ {9, 0.14379807, 0x602fd125c47c0000L, 0x54aba5c5cada5f10L},
+ /* 125 */ {9, 0.14355885, 0x6765c793fa10079dL, 0x3ce9a36f23c0fc90L},
+ /* 126 */ {9, 0.14332233, 0x6f15be069b847e00L, 0x26fb43de2c8cd2a8L},
+ /* 127 */ {9, 0.14308844, 0x7746b3e82a77047fL, 0x12b94793db8486a1L},
+ /* 128 */ {9, 0.14285714, 0x7L, 0x0L},
+ /* 129 */ {9, 0.14262838, 0x894953f7ea890481L, 0xdd5deca404c0156dL},
+ /* 130 */ {9, 0.14240211, 0x932abffea4848200L, 0xbd51373330291de0L},
+ /* 131 */ {9, 0.14217828, 0x9dacb687d3d6a163L, 0x9fa4025d66f23085L},
+ /* 132 */ {9, 0.14195685, 0xa8d8102a44840000L, 0x842530ee2db4949dL},
+ /* 133 */ {9, 0.14173777, 0xb4b60f9d140541e5L, 0x6aa7f2766b03dc25L},
+ /* 134 */ {9, 0.14152100, 0xc15065d4856e4600L, 0x53035ba7ebf32e8dL},
+ /* 135 */ {9, 0.14130649, 0xceb1363f396d23c7L, 0x3d12091fc9fb4914L},
+ /* 136 */ {9, 0.14109421, 0xdce31b2488000000L, 0x28b1cb81b1ef1849L},
+ /* 137 */ {9, 0.14088412, 0xebf12a24bca135c9L, 0x15c35be67ae3e2c9L},
+ /* 138 */ {9, 0.14067617, 0xfbe6f8dbf88f4a00L, 0x42a17bd09be1ff0L},
+ /* 139 */ {8, 0.14047033, 0x1ef156c084ce761L, 0x8bf461f03cf0bbfL},
+ /* 140 */ {8, 0.14026656, 0x20c4e3b94a10000L, 0xf3fbb43f68a32d05L},
+ /* 141 */ {8, 0.14006482, 0x22b0695a08ba421L, 0xd84f44c48564dc19L},
+ /* 142 */ {8, 0.13986509, 0x24b4f35d7a4c100L, 0xbe58ebcce7956abeL},
+ /* 143 */ {8, 0.13966731, 0x26d397284975781L, 0xa5fac463c7c134b7L},
+ /* 144 */ {8, 0.13947147, 0x290d74100000000L, 0x8f19241e28c7d757L},
+ /* 145 */ {8, 0.13927753, 0x2b63b3a37866081L, 0x799a6d046c0ae1aeL},
+ /* 146 */ {8, 0.13908545, 0x2dd789f4d894100L, 0x6566e37d746a9e40L},
+ /* 147 */ {8, 0.13889521, 0x306a35e51b58721L, 0x526887dbfb5f788fL},
+ /* 148 */ {8, 0.13870677, 0x331d01712e10000L, 0x408af3382b8efd3dL},
+ /* 149 */ {8, 0.13852011, 0x35f14200a827c61L, 0x2fbb374806ec05f1L},
+ /* 150 */ {8, 0.13833519, 0x38e858b62216100L, 0x1fe7c0f0afce87feL},
+ /* 151 */ {8, 0.13815199, 0x3c03b2c13176a41L, 0x11003d517540d32eL},
+ /* 152 */ {8, 0.13797047, 0x3f44c9b21000000L, 0x2f5810f98eff0dcL},
+ /* 153 */ {8, 0.13779062, 0x42ad23cef3113c1L, 0xeb72e35e7840d910L},
+ /* 154 */ {8, 0.13761241, 0x463e546b19a2100L, 0xd27de19593dc3614L},
+ /* 155 */ {8, 0.13743580, 0x49f9fc3f96684e1L, 0xbaf391fd3e5e6fc2L},
+ /* 156 */ {8, 0.13726078, 0x4de1c9c5dc10000L, 0xa4bd38c55228c81dL},
+ /* 157 */ {8, 0.13708732, 0x51f77994116d2a1L, 0x8fc5a8de8e1de782L},
+ /* 158 */ {8, 0.13691539, 0x563cd6bb3398100L, 0x7bf9265bea9d3a3bL},
+ /* 159 */ {8, 0.13674498, 0x5ab3bb270beeb01L, 0x69454b325983dccdL},
+ /* 160 */ {8, 0.13657605, 0x5f5e10000000000L, 0x5798ee2308c39df9L},
+ /* 161 */ {8, 0.13640859, 0x643dce0ec16f501L, 0x46e40ba0fa66a753L},
+ /* 162 */ {8, 0.13624257, 0x6954fe21e3e8100L, 0x3717b0870b0db3a7L},
+ /* 163 */ {8, 0.13607797, 0x6ea5b9755f440a1L, 0x2825e6775d11cdebL},
+ /* 164 */ {8, 0.13591477, 0x74322a1c0410000L, 0x1a01a1c09d1b4dacL},
+ /* 165 */ {8, 0.13575295, 0x79fc8b6ae8a46e1L, 0xc9eb0a8bebc8f3eL},
+ /* 166 */ {8, 0.13559250, 0x80072a66d512100L, 0xffe357ff59e6a004L},
+ /* 167 */ {8, 0.13543338, 0x86546633b42b9c1L, 0xe7dfd1be05fa61a8L},
+ /* 168 */ {8, 0.13527558, 0x8ce6b0861000000L, 0xd11ed6fc78f760e5L},
+ /* 169 */ {8, 0.13511908, 0x93c08e16a022441L, 0xbb8db609dd29ebfeL},
+ /* 170 */ {8, 0.13496386, 0x9ae49717f026100L, 0xa71aec8d1813d532L},
+ /* 171 */ {8, 0.13480991, 0xa25577ae24c1a61L, 0x93b612a9f20fbc02L},
+ /* 172 */ {8, 0.13465720, 0xaa15f068e610000L, 0x814fc7b19a67d317L},
+ /* 173 */ {8, 0.13450572, 0xb228d6bf7577921L, 0x6fd9a03f2e0a4b7cL},
+ /* 174 */ {8, 0.13435545, 0xba91158ef5c4100L, 0x5f4615a38d0d316eL},
+ /* 175 */ {8, 0.13420637, 0xc351ad9aec0b681L, 0x4f8876863479a286L},
+ /* 176 */ {8, 0.13405847, 0xcc6db6100000000L, 0x4094d8a3041b60ebL},
+ /* 177 */ {8, 0.13391173, 0xd5e85d09025c181L, 0x32600b8ed883a09bL},
+ /* 178 */ {8, 0.13376614, 0xdfc4e816401c100L, 0x24df8c6eb4b6d1f1L},
+ /* 179 */ {8, 0.13362168, 0xea06b4c72947221L, 0x18097a8ee151acefL},
+ /* 180 */ {8, 0.13347832, 0xf4b139365210000L, 0xbd48cc8ec1cd8e3L},
+ /* 181 */ {8, 0.13333607, 0xffc80497d520961L, 0x3807a8d67485fbL},
+ /* 182 */ {8, 0.13319491, 0x10b4ebfca1dee100L, 0xea5768860b62e8d8L},
+ /* 183 */ {8, 0.13305481, 0x117492de921fc141L, 0xd54faf5b635c5005L},
+ /* 184 */ {8, 0.13291577, 0x123bb2ce41000000L, 0xc14a56233a377926L},
+ /* 185 */ {8, 0.13277777, 0x130a8b6157bdecc1L, 0xae39a88db7cd329fL},
+ /* 186 */ {8, 0.13264079, 0x13e15dede0e8a100L, 0x9c10bde69efa7ab6L},
+ /* 187 */ {8, 0.13250483, 0x14c06d941c0ca7e1L, 0x8ac36c42a2836497L},
+ /* 188 */ {8, 0.13236988, 0x15a7ff487a810000L, 0x7a463c8b84f5ef67L},
+ /* 189 */ {8, 0.13223591, 0x169859ddc5c697a1L, 0x6a8e5f5ad090fd4bL},
+ /* 190 */ {8, 0.13210292, 0x1791c60f6fed0100L, 0x5b91a2943596fc56L},
+ /* 191 */ {8, 0.13197089, 0x18948e8c0e6fba01L, 0x4d4667b1c468e8f0L},
+ /* 192 */ {8, 0.13183981, 0x19a1000000000000L, 0x3fa39ab547994dafL},
+ /* 193 */ {8, 0.13170967, 0x1ab769203dafc601L, 0x32a0a9b2faee1e2aL},
+ /* 194 */ {8, 0.13158046, 0x1bd81ab557f30100L, 0x26357ceac0e96962L},
+ /* 195 */ {8, 0.13145216, 0x1d0367a69fed1ba1L, 0x1a5a6f65caa5859eL},
+ /* 196 */ {8, 0.13132477, 0x1e39a5057d810000L, 0xf08480f672b4e86L},
+ /* 197 */ {8, 0.13119827, 0x1f7b2a18f29ac3e1L, 0x4383340615612caL},
+ /* 198 */ {8, 0.13107265, 0x20c850694c2aa100L, 0xf3c77969ee4be5a2L},
+ /* 199 */ {8, 0.13094791, 0x222173cc014980c1L, 0xe00993cc187c5ec9L},
+ /* 200 */ {8, 0.13082402, 0x2386f26fc1000000L, 0xcd2b297d889bc2b6L},
+ /* 201 */ {8, 0.13070099, 0x24f92ce8af296d41L, 0xbb214d5064862b22L},
+ /* 202 */ {8, 0.13057879, 0x2678863cd0ece100L, 0xa9e1a7ca7ea10e20L},
+ /* 203 */ {8, 0.13045743, 0x280563f0a9472d61L, 0x99626e72b39ea0cfL},
+ /* 204 */ {8, 0.13033688, 0x29a02e1406210000L, 0x899a5ba9c13fafd9L},
+ /* 205 */ {8, 0.13021715, 0x2b494f4efe6d2e21L, 0x7a80a705391e96ffL},
+ /* 206 */ {8, 0.13009822, 0x2d0134ef21cbc100L, 0x6c0cfe23de23042aL},
+ /* 207 */ {8, 0.12998007, 0x2ec84ef4da2ef581L, 0x5e377df359c944ddL},
+ /* 208 */ {8, 0.12986271, 0x309f102100000000L, 0x50f8ac5fc8f53985L},
+ /* 209 */ {8, 0.12974613, 0x3285ee02a1420281L, 0x44497266278e35b7L},
+ /* 210 */ {8, 0.12963031, 0x347d6104fc324100L, 0x382316831f7ee175L},
+ /* 211 */ {8, 0.12951524, 0x3685e47dade53d21L, 0x2c7f377833b8946eL},
+ /* 212 */ {8, 0.12940092, 0x389ff6bb15610000L, 0x2157c761ab4163efL},
+ /* 213 */ {8, 0.12928734, 0x3acc1912ebb57661L, 0x16a7071803cc49a9L},
+ /* 214 */ {8, 0.12917448, 0x3d0acff111946100L, 0xc6781d80f8224fcL},
+ /* 215 */ {8, 0.12906235, 0x3f5ca2e692eaf841L, 0x294092d370a900bL},
+ /* 216 */ {8, 0.12895094, 0x41c21cb8e1000000L, 0xf24f62335024a295L},
+ /* 217 */ {8, 0.12884022, 0x443bcb714399a5c1L, 0xe03b98f103fad6d2L},
+ /* 218 */ {8, 0.12873021, 0x46ca406c81af2100L, 0xcee3d32cad2a9049L},
+ /* 219 */ {8, 0.12862089, 0x496e106ac22aaae1L, 0xbe3f9df9277fdadaL},
+ /* 220 */ {8, 0.12851224, 0x4c27d39fa5410000L, 0xae46f0d94c05e933L},
+ /* 221 */ {8, 0.12840428, 0x4ef825c296e43ca1L, 0x9ef2280fb437a33dL},
+ /* 222 */ {8, 0.12829698, 0x51dfa61f5ad88100L, 0x9039ff426d3f284bL},
+ /* 223 */ {8, 0.12819034, 0x54def7a6d2f16901L, 0x82178c6d6b51f8f4L},
+ /* 224 */ {8, 0.12808435, 0x57f6c10000000000L, 0x74843b1ee4c1e053L},
+ /* 225 */ {8, 0.12797901, 0x5b27ac993df97701L, 0x6779c7f90dc42f48L},
+ /* 226 */ {8, 0.12787431, 0x5e7268b9bbdf8100L, 0x5af23c74f9ad9fe9L},
+ /* 227 */ {8, 0.12777024, 0x61d7a7932ff3d6a1L, 0x4ee7eae2acdc617eL},
+ /* 228 */ {8, 0.12766680, 0x65581f53c8c10000L, 0x43556aa2ac262a0bL},
+ /* 229 */ {8, 0.12756398, 0x68f48a385b8320e1L, 0x3835949593b8ddd1L},
+ /* 230 */ {8, 0.12746176, 0x6cada69ed07c2100L, 0x2d837fbe78458762L},
+ /* 231 */ {8, 0.12736016, 0x70843718cdbf27c1L, 0x233a7e150a54a555L},
+ /* 232 */ {8, 0.12725915, 0x7479027ea1000000L, 0x19561984a50ff8feL},
+ /* 233 */ {8, 0.12715874, 0x788cd40268f39641L, 0xfd211159fe3490fL},
+ /* 234 */ {8, 0.12705891, 0x7cc07b437ecf6100L, 0x6aa563e655033e3L},
+ /* 235 */ {8, 0.12695967, 0x8114cc6220762061L, 0xfbb614b3f2d3b14cL},
+ /* 236 */ {8, 0.12686100, 0x858aa0135be10000L, 0xeac0f8837fb05773L},
+ /* 237 */ {8, 0.12676290, 0x8a22d3b53c54c321L, 0xda6e4c10e8615ca5L},
+ /* 238 */ {8, 0.12666537, 0x8ede496339f34100L, 0xcab755a8d01fa67fL},
+ /* 239 */ {8, 0.12656839, 0x93bde80aec3a1481L, 0xbb95a9ae71aa3e0cL},
+ /* 240 */ {8, 0.12647197, 0x98c29b8100000000L, 0xad0326c296b4f529L},
+ /* 241 */ {8, 0.12637609, 0x9ded549671832381L, 0x9ef9f21eed31b7c1L},
+ /* 242 */ {8, 0.12628075, 0xa33f092e0b1ac100L, 0x91747422be14b0b2L},
+ /* 243 */ {8, 0.12618595, 0xa8b8b452291fe821L, 0x846d550e37b5063dL},
+ /* 244 */ {8, 0.12609168, 0xae5b564ac3a10000L, 0x77df79e9a96c06f6L},
+ /* 245 */ {8, 0.12599794, 0xb427f4b3be74c361L, 0x6bc6019636c7d0c2L},
+ /* 246 */ {8, 0.12590471, 0xba1f9a938041e100L, 0x601c4205aebd9e47L},
+ /* 247 */ {8, 0.12581200, 0xc0435871d1110f41L, 0x54ddc59756f05016L},
+ /* 248 */ {8, 0.12571980, 0xc694446f01000000L, 0x4a0648979c838c18L},
+ /* 249 */ {8, 0.12562811, 0xcd137a5b57ac3ec1L, 0x3f91b6e0bb3a053dL},
+ /* 250 */ {8, 0.12553692, 0xd3c21bcecceda100L, 0x357c299a88ea76a5L},
+ /* 251 */ {8, 0.12544622, 0xdaa150410b788de1L, 0x2bc1e517aecc56e3L},
+ /* 252 */ {8, 0.12535601, 0xe1b24521be010000L, 0x225f56ceb3da9f5dL},
+ /* 253 */ {8, 0.12526629, 0xe8f62df12777c1a1L, 0x1951136d53ad63acL},
+ /* 254 */ {8, 0.12517705, 0xf06e445906fc0100L, 0x1093d504b3cd7d93L},
+ /* 255 */ {8, 0.12508829, 0xf81bc845c81bf801L, 0x824794d1ec1814fL},
+};
+#endif
diff --git a/gnu/lib/libgmp/mpn/tests/add_n.c b/gnu/lib/libgmp/mpn/tests/add_n.c
new file mode 100644
index 0000000..c27d347
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/add_n.c
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 10000000
+#endif
+#ifndef SIZE
+#define SIZE 328
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+
+mp_limb_t
+#if __STDC__
+refmpn_add_n (mp_ptr res_ptr,
+ mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+refmpn_add_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x + y; /* add other addend */
+ cy = (y < x) + cy; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t s2[SIZE];
+ mp_limb_t dx[SIZE+1];
+ mp_limb_t dy[SIZE+1];
+ int cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+
+ mpn_random2 (s1, size);
+ mpn_random2 (s2, size);
+
+ dx[size] = 0x12345678;
+ dy[size] = 0x12345678;
+
+#ifdef PRINT
+ mpn_print (s1, size);
+ mpn_print (s2, size);
+#endif
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_add_n (dx, s1, s2, size);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_add_n: %ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+#endif
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = mpn_add_n (dx, s1, s2, size);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_add_n: %ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+#endif
+
+#ifndef NOCHECK
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i] = 0x7654321;
+ dy[i] = 0x1234567;
+ }
+
+ cyx = refmpn_add_n (dx, s1, s2, size);
+ cyy = mpn_add_n (dy, s1, s2, size);
+ if (cyx != cyy || mpn_cmp (dx, dy, size) != 0
+ || dx[size] != 0x12345678 || dy[size] != 0x12345678)
+ {
+#ifndef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+ printf ("%d ", cyy); mpn_print (dy, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/addmul_1.c b/gnu/lib/libgmp/mpn/tests/addmul_1.c
new file mode 100644
index 0000000..23952a1
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/addmul_1.c
@@ -0,0 +1,223 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+mp_limb_t
+refmpn_addmul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+ register mp_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += (prod_low < x);
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t dx[SIZE+2];
+ mp_limb_t dy[SIZE+2];
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ mp_limb_t xlimb;
+ mp_size_t size;
+ double cyc;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+
+ mpn_random2 (s1, size);
+ mpn_random2 (dy+1, size);
+
+ if (random () % 0x100 == 0)
+ xlimb = 0;
+ else
+ mpn_random2 (&xlimb, 1);
+
+ dy[size+1] = 0x12345678;
+ dy[0] = 0x87654321;
+
+#if defined (PRINT) || defined (XPRINT)
+ printf ("xlimb=%*lX\n", (int) (2 * sizeof(mp_limb_t)), xlimb);
+#endif
+#ifdef PRINT
+ mpn_print (dy+1, size);
+ mpn_print (s1, size);
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_addmul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ cyc = ((double) t * CLOCK) / (OPS * 1000.0);
+ printf ("refmpn_addmul_1: %5ldms (%.2f cycles/limb) [%.2f Gb/s]\n",
+ t,
+ cyc,
+ CLOCK/cyc*BITS_PER_MP_LIMB*BITS_PER_MP_LIMB);
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyy = mpn_addmul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ cyc = ((double) t * CLOCK) / (OPS * 1000.0);
+ printf ("mpn_addmul_1: %5ldms (%.2f cycles/limb) [%.2f Gb/s]\n",
+ t,
+ cyc,
+ CLOCK/cyc*BITS_PER_MP_LIMB*BITS_PER_MP_LIMB);
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ cyx = refmpn_addmul_1 (dx+1, s1, size, xlimb);
+ cyy = mpn_addmul_1 (dy+1, s1, size, xlimb);
+
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+
+#ifndef NOCHECK
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
+ {
+#ifndef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/divmod_1.c b/gnu/lib/libgmp/mpn/tests/divmod_1.c
new file mode 100644
index 0000000..f6b541e
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/divmod_1.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 1000
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+main ()
+{
+ mp_limb_t nptr[SIZE];
+ mp_limb_t qptr[SIZE];
+ mp_limb_t pptr[SIZE];
+ mp_limb_t dlimb, rlimb, plimb;
+ mp_size_t nsize, qsize, psize;
+ int test;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ nsize = random () % SIZE + 1;
+#else
+ nsize = SIZE;
+#endif
+
+ mpn_random2 (nptr, nsize);
+
+ mpn_random2 (&dlimb, 1);
+ if (dlimb == 0)
+ abort ();
+
+ rlimb = mpn_divmod_1 (qptr, nptr, nsize, dlimb);
+ qsize = nsize - (qptr[nsize - 1] == 0);
+ if (qsize == 0)
+ {
+ plimb = rlimb;
+ psize = qsize;
+ }
+ else
+ {
+ plimb = mpn_mul_1 (pptr, qptr, qsize, dlimb);
+ psize = qsize;
+ plimb += mpn_add_1 (pptr, pptr, psize, rlimb);
+ }
+ if (plimb != 0)
+ pptr[psize++] = plimb;
+
+
+ if (nsize != psize || mpn_cmp (nptr, pptr, nsize) != 0)
+ abort ();
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/tests/divrem.c b/gnu/lib/libgmp/mpn/tests/divrem.c
new file mode 100644
index 0000000..6eafc99
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/divrem.c
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 100
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+main ()
+{
+ mp_limb_t nptr[2 * SIZE];
+ mp_limb_t dptr[SIZE];
+ mp_limb_t qptr[2 * SIZE];
+ mp_limb_t pptr[2 * SIZE];
+ mp_limb_t rptr[2 * SIZE];
+ mp_size_t nsize, dsize, qsize, rsize, psize;
+ int test;
+ mp_limb_t qlimb;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ nsize = random () % (2 * SIZE) + 1;
+ dsize = random () % nsize + 1;
+#else
+ nsize = 2 * SIZE;
+ dsize = SIZE;
+#endif
+
+ mpn_random2 (nptr, nsize);
+ mpn_random2 (dptr, dsize);
+ dptr[dsize - 1] |= (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+
+ MPN_COPY (rptr, nptr, nsize);
+ qlimb = mpn_divrem (qptr, (mp_size_t) 0, rptr, nsize, dptr, dsize);
+ rsize = dsize;
+ qsize = nsize - dsize;
+ qptr[qsize] = qlimb;
+ qsize += qlimb;
+ if (qsize == 0 || qsize > 2 * SIZE)
+ {
+ continue; /* bogus */
+ }
+ else
+ {
+ mp_limb_t cy;
+ if (qsize > dsize)
+ mpn_mul (pptr, qptr, qsize, dptr, dsize);
+ else
+ mpn_mul (pptr, dptr, dsize, qptr, qsize);
+ psize = qsize + dsize;
+ psize -= pptr[psize - 1] == 0;
+ cy = mpn_add (pptr, pptr, psize, rptr, rsize);
+ pptr[psize] = cy;
+ psize += cy;
+ }
+
+ if (nsize != psize || mpn_cmp (nptr, pptr, nsize) != 0)
+ abort ();
+ }
+}
diff --git a/gnu/lib/libgmp/mpn/tests/lshift.c b/gnu/lib/libgmp/mpn/tests/lshift.c
new file mode 100644
index 0000000..f50c5dc
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/lshift.c
@@ -0,0 +1,226 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 10000000
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+mp_limb_t
+refmpn_lshift (wp, up, usize, cnt)
+ register mp_ptr wp;
+ register mp_srcptr up;
+ mp_size_t usize;
+ register unsigned int cnt;
+{
+ register mp_limb_t high_limb, low_limb;
+ register unsigned sh_1, sh_2;
+ register mp_size_t i;
+ mp_limb_t retval;
+
+#ifdef DEBUG
+ if (usize == 0 || cnt == 0)
+ abort ();
+#endif
+
+ sh_1 = cnt;
+#if 0
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from high end to low end, to allow specified input/output
+ overlapping. */
+ for (i = usize - 1; i >= 0; i--)
+ wp[i] = up[i];
+ }
+ return 0;
+ }
+#endif
+
+ wp += 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while (--i >= 0)
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
+
+#ifndef CNT
+#define CNT 4
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t dx[SIZE+2];
+ mp_limb_t dy[SIZE+2];
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ int cnt = CNT;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+ mpn_random2 (s1, size);
+
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+
+#ifdef PRINT
+ mpn_print (s1, size);
+#endif
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_lshift (dx+1, s1, size, cnt);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_lshift: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx); mpn_print (dx+1, size);
+#endif
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyy = mpn_lshift (dx+1, s1, size, cnt);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_lshift: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy); mpn_print (dx+1, size);
+#endif
+
+#ifndef NOCHECK
+ /* Put garbage in the destination. */
+ for (i = 1; i <= size; i++)
+ {
+ dx[i] = 0x7654321;
+ dy[i] = 0x1234567;
+ }
+
+ cyx = refmpn_lshift (dx+1, s1, size, cnt);
+ cyy = mpn_lshift (dy+1, s1, size, cnt);
+
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
+ {
+#ifndef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/mul_1.c b/gnu/lib/libgmp/mpn/tests/mul_1.c
new file mode 100644
index 0000000..2b522fa
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/mul_1.c
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+mp_limb_t
+refmpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t dx[SIZE+2];
+ mp_limb_t dy[SIZE+2];
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ mp_limb_t xlimb;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+
+ mpn_random2 (s1, size);
+ mpn_random2 (dy+1, size);
+
+ if (random () % 0x100 == 0)
+ xlimb = 0;
+ else
+ mpn_random2 (&xlimb, 1);
+
+ dy[size+1] = 0x12345678;
+ dy[0] = 0x87654321;
+
+#if defined (PRINT) || defined (XPRINT)
+ printf ("xlimb=%*lX\n", (int) (2 * sizeof(mp_limb_t)), xlimb);
+#endif
+#ifdef PRINT
+ mpn_print (s1, size);
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_mul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_mul_1: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyy = mpn_mul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_mul_1: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+
+ cyx = refmpn_mul_1 (dx+1, s1, size, xlimb);
+ cyy = mpn_mul_1 (dy+1, s1, size, xlimb);
+
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+
+#ifndef NOCHECK
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
+ {
+#ifndef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/rshift.c b/gnu/lib/libgmp/mpn/tests/rshift.c
new file mode 100644
index 0000000..2482bf3
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/rshift.c
@@ -0,0 +1,227 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 10000000
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+mp_limb_t
+refmpn_rshift (wp, up, usize, cnt)
+ register mp_ptr wp;
+ register mp_srcptr up;
+ mp_size_t usize;
+ register unsigned int cnt;
+{
+ register mp_limb_t high_limb, low_limb;
+ register unsigned sh_1, sh_2;
+ register mp_size_t i;
+ mp_limb_t retval;
+
+#ifdef DEBUG
+ if (usize == 0 || cnt == 0)
+ abort ();
+#endif
+
+ sh_1 = cnt;
+#if 0
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from low end to high end, to allow specified input/output
+ overlapping. */
+ for (i = 0; i < usize; i++)
+ wp[i] = up[i];
+ }
+ return 0;
+ }
+#endif
+
+ wp -= 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+
+ for (i = 1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ low_limb >>= sh_1;
+ wp[i] = low_limb;
+
+ return retval;
+}
+
+#ifndef CNT
+#define CNT 4
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t dx[SIZE+2];
+ mp_limb_t dy[SIZE+2];
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ int cnt = CNT;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+ mpn_random2 (s1, size);
+
+ dx[size+1] = 0x12345678;
+ dy[size+1] = 0x12345678;
+ dx[0] = 0x87654321;
+ dy[0] = 0x87654321;
+
+#ifdef PRINT
+ mpn_print (s1, size);
+#endif
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_rshift (dx+1, s1, size, cnt);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_rshift: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx); mpn_print (dx+1, size);
+#endif
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyy = mpn_rshift (dx+1, s1, size, cnt);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_rshift: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy); mpn_print (dx+1, size);
+#endif
+
+#ifndef NOCHECK
+ /* Put garbage in the destination. */
+ for (i = 1; i <= size; i++)
+ {
+ dx[i] = 0x7654321;
+ dy[i] = 0x1234567;
+ }
+
+ cyx = refmpn_rshift (dx+1, s1, size, cnt);
+ cyy = mpn_rshift (dy+1, s1, size, cnt);
+
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
+ {
+#ifndef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/sub_n.c b/gnu/lib/libgmp/mpn/tests/sub_n.c
new file mode 100644
index 0000000..2b9031b
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/sub_n.c
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 10000000
+#endif
+#ifndef SIZE
+#define SIZE 328
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+
+mp_limb_t
+#if __STDC__
+refmpn_sub_n (mp_ptr res_ptr,
+ mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+refmpn_sub_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy = (y > x) + cy; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t s2[SIZE];
+ mp_limb_t dx[SIZE+1];
+ mp_limb_t dy[SIZE+1];
+ int cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+
+ mpn_random2 (s1, size);
+ mpn_random2 (s2, size);
+
+ dx[size] = 0x12345678;
+ dy[size] = 0x12345678;
+
+#ifdef PRINT
+ mpn_print (s1, size);
+ mpn_print (s2, size);
+#endif
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_sub_n (dx, s1, s2, size);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_sub_n: %ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+#endif
+
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = mpn_sub_n (dx, s1, s2, size);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_sub_n: %ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+#ifdef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+#endif
+
+#ifndef NOCHECK
+ /* Put garbage in the destination. */
+ for (i = 0; i < size; i++)
+ {
+ dx[i] = 0x7654321;
+ dy[i] = 0x1234567;
+ }
+
+ cyx = refmpn_sub_n (dx, s1, s2, size);
+ cyy = mpn_sub_n (dy, s1, s2, size);
+ if (cyx != cyy || mpn_cmp (dx, dy, size) != 0
+ || dx[size] != 0x12345678 || dy[size] != 0x12345678)
+ {
+#ifndef PRINT
+ printf ("%d ", cyx); mpn_print (dx, size);
+ printf ("%d ", cyy); mpn_print (dy, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/submul_1.c b/gnu/lib/libgmp/mpn/tests/submul_1.c
new file mode 100644
index 0000000..0e464e6
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/submul_1.c
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef USG
+#include <sys/time.h>
+#include <sys/resource.h>
+
+unsigned long
+cputime ()
+{
+ struct rusage rus;
+
+ getrusage (0, &rus);
+ return rus.ru_utime.tv_sec * 1000 + rus.ru_utime.tv_usec / 1000;
+}
+#else
+#include <time.h>
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 1000000
+#endif
+
+#if CLOCKS_PER_SEC >= 10000
+#define CLOCK_TO_MILLISEC(cl) ((cl) / (CLOCKS_PER_SEC / 1000))
+#else
+#define CLOCK_TO_MILLISEC(cl) ((cl) * 1000 / CLOCKS_PER_SEC)
+#endif
+
+unsigned long
+cputime ()
+{
+ return CLOCK_TO_MILLISEC (clock ());
+}
+#endif
+
+#define M * 1000000
+
+#ifndef CLOCK
+#if defined (__m88k__)
+#define CLOCK 20 M
+#elif defined (__i386__)
+#define CLOCK (16.666667 M)
+#elif defined (__m68k__)
+#define CLOCK (20 M)
+#elif defined (_IBMR2)
+#define CLOCK (25 M)
+#elif defined (__sparc__)
+#define CLOCK (20 M)
+#elif defined (__sun__)
+#define CLOCK (20 M)
+#elif defined (__mips)
+#define CLOCK (40 M)
+#elif defined (__hppa__)
+#define CLOCK (50 M)
+#elif defined (__alpha)
+#define CLOCK (133 M)
+#else
+#error "Don't know CLOCK of your machine"
+#endif
+#endif
+
+#ifndef OPS
+#define OPS 20000000
+#endif
+#ifndef SIZE
+#define SIZE 496
+#endif
+#ifndef TIMES
+#define TIMES OPS/SIZE
+#else
+#undef OPS
+#define OPS (SIZE*TIMES)
+#endif
+
+mp_limb_t
+refmpn_submul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ mp_size_t s1_size;
+ register mp_limb_t s2_limb;
+{
+ register mp_limb_t cy_limb;
+ register mp_size_t j;
+ register mp_limb_t prod_high, prod_low;
+ register mp_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += (prod_low > x);
+ res_ptr[j] = prod_low;
+ }
+ while (++j != 0);
+
+ return cy_limb;
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_limb_t s1[SIZE];
+ mp_limb_t dx[SIZE+2];
+ mp_limb_t dy[SIZE+2];
+ mp_limb_t cyx, cyy;
+ int i;
+ long t0, t;
+ int test;
+ mp_limb_t xlimb;
+ mp_size_t size;
+
+ for (test = 0; ; test++)
+ {
+#ifdef RANDOM
+ size = (random () % SIZE + 1);
+#else
+ size = SIZE;
+#endif
+
+ mpn_random2 (s1, size);
+ mpn_random2 (dy+1, size);
+
+ if (random () % 0x100 == 0)
+ xlimb = 0;
+ else
+ mpn_random2 (&xlimb, 1);
+
+ dy[size+1] = 0x12345678;
+ dy[0] = 0x87654321;
+
+#if defined (PRINT) || defined (XPRINT)
+ printf ("xlimb=%*lX\n", (int) (2 * sizeof(mp_limb_t)), xlimb);
+#endif
+#ifdef PRINT
+ mpn_print (dy+1, size);
+ mpn_print (s1, size);
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyx = refmpn_submul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("refmpn_submul_1: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ t0 = cputime();
+ for (i = 0; i < TIMES; i++)
+ cyy = mpn_submul_1 (dx+1, s1, size, xlimb);
+ t = cputime() - t0;
+#if TIMES != 1
+ printf ("mpn_submul_1: %5ldms (%.2f cycles/limb)\n",
+ t,
+ ((double) t * CLOCK) / (OPS * 1000.0));
+#endif
+
+ MPN_COPY (dx, dy, size+2);
+ cyx = refmpn_submul_1 (dx+1, s1, size, xlimb);
+ cyy = mpn_submul_1 (dy+1, s1, size, xlimb);
+
+#ifdef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+
+#ifndef NOCHECK
+ if (cyx != cyy || mpn_cmp (dx, dy, size+2) != 0
+ || dx[size+1] != 0x12345678 || dx[0] != 0x87654321)
+ {
+#ifndef PRINT
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyx);
+ mpn_print (dx+1, size);
+ printf ("%*lX ", (int) (2 * sizeof(mp_limb_t)), cyy);
+ mpn_print (dy+1, size);
+#endif
+ abort();
+ }
+#endif
+ }
+}
+
+mpn_print (mp_ptr p, mp_size_t size)
+{
+ mp_size_t i;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ printf ("%0*lX", (int) (2 * sizeof(mp_limb_t)), p[i]);
+#ifdef SPACE
+ if (i != 0)
+ printf (" ");
+#endif
+ }
+ puts ("");
+}
diff --git a/gnu/lib/libgmp/mpn/tests/tst-addsub.c b/gnu/lib/libgmp/mpn/tests/tst-addsub.c
new file mode 100644
index 0000000..e02b9d5
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/tests/tst-addsub.c
@@ -0,0 +1,164 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define ADD 1
+#define SUB 2
+
+#ifndef METHOD
+#define METHOD ADD
+#endif
+
+#if METHOD == ADD
+#define REFCALL refmpn_add_n
+#define TESTCALL mpn_add_n
+#endif
+
+#if METHOD == SUB
+#define REFCALL refmpn_sub_n
+#define TESTCALL mpn_sub_n
+#endif
+
+mp_limb_t refmpn_add_n ();
+mp_limb_t refmpn_sub_n ();
+
+#define SIZE 100
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mp_size_t alloc_size, max_size, size, i, cumul_size;
+ mp_ptr s1, s2, dx, dy;
+ int s1_align, s2_align, d_align;
+ long pass, n_passes;
+ mp_limb_t cx, cy;
+
+ max_size = SIZE;
+ n_passes = 1000000;
+
+ argc--; argv++;
+ if (argc)
+ {
+ max_size = atol (*argv);
+ argc--; argv++;
+ }
+
+ alloc_size = max_size + 32;
+ s1 = malloc (alloc_size * BYTES_PER_MP_LIMB);
+ s2 = malloc (alloc_size * BYTES_PER_MP_LIMB);
+ dx = malloc (alloc_size * BYTES_PER_MP_LIMB);
+ dy = malloc (alloc_size * BYTES_PER_MP_LIMB);
+
+ cumul_size = 0;
+ for (pass = 0; pass < n_passes; pass++)
+ {
+ cumul_size += size;
+ if (cumul_size >= 1000000)
+ {
+ cumul_size -= 1000000;
+ printf ("%d ", pass); fflush (stdout);
+ }
+ s1_align = random () % 32;
+ s2_align = random () % 32;
+ d_align = random () % 32;
+
+ size = random () % max_size + 1;
+
+ mpn_random2 (s1 + s1_align, size);
+ mpn_random2 (s2 + s2_align, size);
+
+ for (i = 0; i < alloc_size; i++)
+ dx[i] = dy[i] = i + 0x9876500;
+
+ cx = TESTCALL (dx + d_align, s1 + s1_align, s2 + s2_align, size);
+ cy = REFCALL (dy + d_align, s1 + s1_align, s2 + s2_align, size);
+
+ if (cx != cy || mpn_cmp (dx, dy, alloc_size) != 0)
+ abort ();
+ }
+
+ printf ("%d passes OK\n", n_passes);
+ exit (0);
+}
+
+mp_limb_t
+#if __STDC__
+refmpn_add_n (mp_ptr res_ptr,
+ mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+refmpn_add_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x + y; /* add other addend */
+ cy = (y < x) + cy; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
+
+mp_limb_t
+#if __STDC__
+refmpn_sub_n (mp_ptr res_ptr,
+ mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
+#else
+refmpn_sub_n (res_ptr, s1_ptr, s2_ptr, size)
+ register mp_ptr res_ptr;
+ register mp_srcptr s1_ptr;
+ register mp_srcptr s2_ptr;
+ mp_size_t size;
+#endif
+{
+ register mp_limb_t x, y, cy;
+ register mp_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = (y < cy); /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy = (y > x) + cy; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while (++j != 0);
+
+ return cy;
+}
diff --git a/gnu/lib/libgmp/mpn/x86/add_n.S b/gnu/lib/libgmp/mpn/x86/add_n.S
new file mode 100644
index 0000000..5bbbd0d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/add_n.S
@@ -0,0 +1,106 @@
+/* i80386 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+sum in a third limb vector.
+
+Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ s2_ptr (sp + 12)
+ size (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_add_n)
+C_SYMBOL_NAME(__mpn_add_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/addmul_1.S b/gnu/lib/libgmp/mpn/x86/addmul_1.S
new file mode 100644
index 0000000..c11209d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/addmul_1.S
@@ -0,0 +1,76 @@
+/* i80386 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+
+Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_addmul_1)
+C_SYMBOL_NAME(__mpn_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/lshift.S b/gnu/lib/libgmp/mpn/x86/lshift.S
new file mode 100644
index 0000000..8173b92
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/lshift.S
@@ -0,0 +1,85 @@
+/* i80386 __mpn_lshift --
+
+Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s_ptr (sp + 8)
+ size (sp + 12)
+ cnt (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_lshift)
+C_SYMBOL_NAME(__mpn_lshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* res_ptr */
+ movl 20(%esp),%esi /* s_ptr */
+ movl 24(%esp),%edx /* size */
+ movl 28(%esp),%ecx /* cnt */
+
+ subl $4,%esi /* adjust s_ptr */
+
+ movl (%esi,%edx,4),%ebx /* read most significant limb */
+ xorl %eax,%eax
+ shldl %cl,%ebx,%eax /* compute carry limb */
+ decl %edx
+ jz Lend
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%edx
+ jnz L1 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */
+ shldl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ decl %edx
+L1: movl (%esi,%edx,4),%eax
+ shldl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz Loop
+
+ shll %cl,%eax /* compute least significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend: shll %cl,%ebx /* compute least significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/mul_1.S b/gnu/lib/libgmp/mpn/x86/mul_1.S
new file mode 100644
index 0000000..b271399
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/mul_1.S
@@ -0,0 +1,75 @@
+/* i80386 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+
+Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_mul_1)
+C_SYMBOL_NAME(__mpn_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/README b/gnu/lib/libgmp/mpn/x86/pentium/README
new file mode 100644
index 0000000..d73b082
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/README
@@ -0,0 +1,26 @@
+This directory contains mpn functions optimized for Intel Pentium
+processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. Pentium doesn't allocate cache lines on writes, unlike most other modern
+processors. Since the functions in the mpn class do array writes, we have to
+handle allocating the destination cache lines by reading a word from it in the
+loops, to achieve the best performance.
+
+2. Pairing of memory operations requires that the two issued operations refer
+to different cache banks. The simplest way to insure this is to read/write
+two words from the same object. If we make operations on different objects,
+they might or might not be to the same cache bank.
+
+STATUS
+
+1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium
+documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
+or 5 cycles/limb asymptotically.
+
+2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
+overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb.
+
+3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
+should...
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/add_n.S b/gnu/lib/libgmp/mpn/x86/pentium/add_n.S
new file mode 100644
index 0000000..ac6f281
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/add_n.S
@@ -0,0 +1,130 @@
+/* Pentium __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+
+Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ s2_ptr (sp + 12)
+ size (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_add_n)
+C_SYMBOL_NAME(__mpn_add_n:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ adcl %ebx,%eax
+ movl 12(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ adcl %ebx,%eax
+ movl 20(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %ebx,%eax
+ movl 28(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/addmul_1.S b/gnu/lib/libgmp/mpn/x86/pentium/addmul_1.S
new file mode 100644
index 0000000..7cfa5db
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/addmul_1.S
@@ -0,0 +1,83 @@
+/* Pentium __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ the result to a second limb vector.
+
+Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_addmul_1)
+C_SYMBOL_NAME(__mpn_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/lshift.S b/gnu/lib/libgmp/mpn/x86/pentium/lshift.S
new file mode 100644
index 0000000..b298983
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/lshift.S
@@ -0,0 +1,217 @@
+/* Pentium optimized __mpn_lshift --
+
+Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s_ptr (sp + 8)
+ size (sp + 12)
+ cnt (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_lshift)
+C_SYMBOL_NAME(__mpn_lshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Lnormal
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
+ leal (%esi,%ebp,4),%eax
+ cmpl %eax,%edi
+ jnc Lspecial /* jump if res_ptr >= s_ptr + size */
+
+Lnormal:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Lend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Loop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ shldl %cl,%ebx,%edx
+ shldl %cl,%eax,%ebx
+ movl %edx,-8(%edi)
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ shldl %cl,%edx,%eax
+ shldl %cl,%ebx,%edx
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebp
+ jnz Loop
+
+Lend: popl %ebp
+ andl $7,%ebp
+ jz Lend2
+Loop2: movl (%esi),%eax
+ shldl %cl,%eax,%edx
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebp
+ jnz Loop2
+
+Lend2: shll %cl,%edx /* compute least significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Lspecial:
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ addl %edx,%edx
+ incl %ebp
+ decl %ebp
+ jz LLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+LLoop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ adcl %ebx,%ebx
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebx,%ebx
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi /* use leal not to clobber carry */
+ leal 32(%edi),%edi
+ decl %ebp
+ jnz LLoop
+
+LLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz LLend2
+ addl %eax,%eax /* restore carry from eax */
+LLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebx,(%edi)
+
+ leal 4(%esi),%esi /* use leal not to clobber carry */
+ leal 4(%edi),%edi
+ decl %ebp
+ jnz LLoop2
+
+ jmp LL1
+LLend2: addl %eax,%eax /* restore carry from eax */
+LL1: movl %edx,(%edi) /* store last limb */
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/mul_1.S b/gnu/lib/libgmp/mpn/x86/pentium/mul_1.S
new file mode 100644
index 0000000..4ac3050
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/mul_1.S
@@ -0,0 +1,79 @@
+/* Pentium __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ the result in a second limb vector.
+
+Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_mul_1)
+C_SYMBOL_NAME(__mpn_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/rshift.S b/gnu/lib/libgmp/mpn/x86/pentium/rshift.S
new file mode 100644
index 0000000..38398ed
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/rshift.S
@@ -0,0 +1,217 @@
+/* Pentium optimized __mpn_rshift --
+
+Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s_ptr (sp + 8)
+ size (sp + 12)
+ cnt (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_rshift)
+C_SYMBOL_NAME(__mpn_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Lnormal
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc Lspecial /* jump if res_ptr + 1 >= s_ptr */
+ leal (%edi,%ebp,4),%eax
+ cmpl %eax,%esi
+ jnc Lspecial /* jump if s_ptr >= res_ptr + size */
+
+Lnormal:
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Lend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ shrdl %cl,%ebx,%edx
+ shrdl %cl,%eax,%ebx
+ movl %edx,8(%edi)
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ shrdl %cl,%edx,%eax
+ shrdl %cl,%ebx,%edx
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebp
+ jnz Loop
+
+Lend: popl %ebp
+ andl $7,%ebp
+ jz Lend2
+Loop2: movl (%esi),%eax
+ shrdl %cl,%eax,%edx /* compute result limb */
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebp
+ jnz Loop2
+
+Lend2: shrl %cl,%edx /* compute most significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Lspecial:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ shrl $1,%edx
+ incl %ebp
+ decl %ebp
+ jz LLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+LLoop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,(%edi)
+ rcrl $1,%edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ rcrl $1,%ebx
+ movl %edx,-8(%edi)
+ rcrl $1,%eax
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ rcrl $1,%edx
+ movl %eax,-16(%edi)
+ rcrl $1,%ebx
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,-24(%edi)
+ rcrl $1,%edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi /* use leal not to clobber carry */
+ leal -32(%edi),%edi
+ decl %ebp
+ jnz LLoop
+
+LLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz LLend2
+ addl %eax,%eax /* restore carry from eax */
+LLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ rcrl $1,%edx
+ movl %ebx,(%edi)
+
+ leal -4(%esi),%esi /* use leal not to clobber carry */
+ leal -4(%edi),%edi
+ decl %ebp
+ jnz LLoop2
+
+ jmp LL1
+LLend2: addl %eax,%eax /* restore carry from eax */
+LL1: movl %edx,(%edi) /* store last limb */
+
+ movl $0,%eax
+ rcrl $1,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/sub_n.S b/gnu/lib/libgmp/mpn/x86/pentium/sub_n.S
new file mode 100644
index 0000000..d1a2bc0
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/sub_n.S
@@ -0,0 +1,130 @@
+/* Pentium __mpn_sub_n -- Subtract two limb vectors of the same length > 0
+ and store difference in a third limb vector.
+
+Copyright (C) 1992, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ s2_ptr (sp + 12)
+ size (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_sub_n)
+C_SYMBOL_NAME(__mpn_sub_n:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ sbbl %ebx,%eax
+ movl 12(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ sbbl %ebx,%eax
+ movl 20(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ sbbl %ebx,%eax
+ movl 28(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/pentium/submul_1.S b/gnu/lib/libgmp/mpn/x86/pentium/submul_1.S
new file mode 100644
index 0000000..adf2d63
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/pentium/submul_1.S
@@ -0,0 +1,83 @@
+/* Pentium __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ the result from a second limb vector.
+
+Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_submul_1)
+C_SYMBOL_NAME(__mpn_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/rshift.S b/gnu/lib/libgmp/mpn/x86/rshift.S
new file mode 100644
index 0000000..9abbf9a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/rshift.S
@@ -0,0 +1,87 @@
+/* i80386 __mpn_rshift --
+
+Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s_ptr (sp + 8)
+ size (sp + 12)
+ cnt (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_rshift)
+C_SYMBOL_NAME(__mpn_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* res_ptr */
+ movl 20(%esp),%esi /* s_ptr */
+ movl 24(%esp),%edx /* size */
+ movl 28(%esp),%ecx /* cnt */
+
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx /* read least significant limb */
+ xorl %eax,%eax
+ shrdl %cl,%ebx,%eax /* compute carry limb */
+ incl %edx
+ jz Lend
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%edx
+ jnz L1 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop: movl (%esi,%edx,4),%ebx /* load next higher limb */
+ shrdl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ incl %edx
+L1: movl (%esi,%edx,4),%eax
+ shrdl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz Loop
+
+ shrl %cl,%eax /* compute most significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend: shrl %cl,%ebx /* compute most significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/sub_n.S b/gnu/lib/libgmp/mpn/x86/sub_n.S
new file mode 100644
index 0000000..1774f3a
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/sub_n.S
@@ -0,0 +1,106 @@
+/* i80386 __mpn_sub_n -- Add two limb vectors of the same length > 0 and store
+ sum in a third limb vector.
+
+Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ s2_ptr (sp + 12)
+ size (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(__mpn_sub_n)
+C_SYMBOL_NAME(__mpn_sub_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ sbbl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ sbbl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ sbbl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ sbbl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ sbbl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ sbbl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ sbbl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ sbbl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/submul_1.S b/gnu/lib/libgmp/mpn/x86/submul_1.S
new file mode 100644
index 0000000..730e732
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/submul_1.S
@@ -0,0 +1,76 @@
+/* i80386 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ the result from a second limb vector.
+
+Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/*
+ INPUT PARAMETERS
+ res_ptr (sp + 4)
+ s1_ptr (sp + 8)
+ size (sp + 12)
+ s2_limb (sp + 16)
+*/
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(__mpn_submul_1)
+C_SYMBOL_NAME(__mpn_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
diff --git a/gnu/lib/libgmp/mpn/x86/syntax.h b/gnu/lib/libgmp/mpn/x86/syntax.h
new file mode 100644
index 0000000..c53c73c
--- /dev/null
+++ b/gnu/lib/libgmp/mpn/x86/syntax.h
@@ -0,0 +1,62 @@
+/* asm.h -- Definitions for x86 syntax variations.
+
+Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+
+#undef ALIGN
+
+#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#if defined (BSD_SYNTAX)
+#define ALIGN(log) .align log
+#endif
+#if defined (ELF_SYNTAX)
+#define ALIGN(log) .align 1<<(log)
+#endif
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
diff --git a/gnu/lib/libgmp/mpn_add.c b/gnu/lib/libgmp/mpn_add.c
new file mode 100644
index 0000000..10502a8
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_add.c
@@ -0,0 +1,141 @@
+/* mpn_add -- Add two low-level integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Add ADD1_PTR/ADD1_SIZE and ADD2_PTR/ADD2_SIZE and store the first
+ ADD1_SIZE words of the result at SUM_PTR.
+
+ Return 1 if carry out was generated, return 0 otherwise.
+
+ Argument constraint: ADD1_SIZE >= ADD2_SIZE.
+
+ The size of SUM can be calculated as ADD1_SIZE + the return value. */
+
+mp_limb
+#ifdef __STDC__
+mpn_add (mp_ptr sum_ptr,
+ mp_srcptr add1_ptr, mp_size add1_size,
+ mp_srcptr add2_ptr, mp_size add2_size)
+#else
+mpn_add (sum_ptr, add1_ptr, add1_size, add2_ptr, add2_size)
+ mp_ptr sum_ptr;
+ mp_srcptr add1_ptr;
+ mp_size add1_size;
+ mp_srcptr add2_ptr;
+ mp_size add2_size;
+#endif
+{
+ mp_limb a1, a2, sum;
+ mp_size j;
+
+ /* The loop counter and index J goes from some negative value to zero.
+ This way the loops become faster. Need to offset the base pointers
+ to take care of the negative indices. */
+
+ j = -add2_size;
+ if (j == 0)
+ goto add2_finished;
+
+ add1_ptr -= j;
+ add2_ptr -= j;
+ sum_ptr -= j;
+
+ /* There are two do-loops, marked NON-CARRY LOOP and CARRY LOOP that
+ jump between each other. The first loop is for when the previous
+ addition didn't produce a carry-out; the second is for the
+ complementary case. */
+
+ /* NON-CARRY LOOP */
+ do
+ {
+ a1 = add1_ptr[j];
+ a2 = add2_ptr[j];
+ sum = a1 + a2;
+ sum_ptr[j] = sum;
+ if (sum < a2)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ /* We have exhausted ADD2. Just copy ADD1 to SUM, and return
+ 0 as an indication of no carry-out. */
+
+ add2_finished:
+ /* Immediate return if the copy would be a no-op. */
+ if (sum_ptr == add1_ptr)
+ return 0;
+
+ j = add2_size - add1_size;
+ add1_ptr -= j;
+ sum_ptr -= j;
+
+ while (j < 0)
+ {
+ sum_ptr[j] = add1_ptr[j];
+ j++;
+ }
+ return 0;
+
+ /* CARRY LOOP */
+ do
+ {
+ a1 = add1_ptr[j];
+ a2 = add2_ptr[j];
+ sum = a1 + a2 + 1;
+ sum_ptr[j] = sum;
+ if (sum > a2)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ j = add2_size - add1_size;
+ add1_ptr -= j;
+ sum_ptr -= j;
+
+ while (j < 0)
+ {
+ a1 = add1_ptr[j];
+ sum = a1 + 1;
+ sum_ptr[j] = sum;
+ if (sum > 0)
+ goto copy_add1;
+ j++;
+ }
+ return 1;
+
+ copy_add1:
+ if (sum_ptr == add1_ptr)
+ return 0;
+
+ j++;
+ while (j < 0)
+ {
+ sum_ptr[j] = add1_ptr[j];
+ j++;
+ }
+
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpn_cmp.c b/gnu/lib/libgmp/mpn_cmp.c
new file mode 100644
index 0000000..11f39ca
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_cmp.c
@@ -0,0 +1,52 @@
+/* mpn_cmp -- Compare two low-level natural-number integers.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ There are no restrictions on the relative sizes of
+ the two arguments.
+ Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. */
+
+int
+#ifdef __STDC__
+mpn_cmp (mp_srcptr op1_ptr, mp_srcptr op2_ptr, mp_size size)
+#else
+mpn_cmp (op1_ptr, op2_ptr, size)
+ mp_srcptr op1_ptr;
+ mp_srcptr op2_ptr;
+ mp_size size;
+#endif
+{
+ mp_size i;
+ mp_limb op1_word, op2_word;
+
+ for (i = size - 1; i >= 0; i--)
+ {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if (op1_word != op2_word)
+ goto diff;
+ }
+ return 0;
+ diff:
+ return (op1_word > op2_word) ? 1 : -1;
+}
diff --git a/gnu/lib/libgmp/mpn_div.c b/gnu/lib/libgmp/mpn_div.c
new file mode 100644
index 0000000..8609206
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_div.c
@@ -0,0 +1,321 @@
+/* mpn_div -- Divide natural numbers, producing both remainder and
+ quotient.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Divide num (NUM_PTR/NUM_SIZE) by den (DEN_PTR/DEN_SIZE) and write
+ the quotient at QUOT_PTR and the remainder at NUM_PTR.
+
+ Return 0 or 1, depending on if the quotient size is (NSIZE - DSIZE)
+ or (NSIZE - DSIZE + 1).
+
+ Argument constraints:
+ 1. The most significant bit of d must be set.
+ 2. QUOT_PTR != DEN_PTR and QUOT_PTR != NUM_PTR, i.e. the quotient storage
+ area must be distinct from either input operands.
+
+ The exact sizes of the quotient and remainder must be determined
+ by the caller, in spite of the return value. The return value just
+ informs the caller about if the highest digit is written or not, and
+ it may very well be 0. */
+
+/* THIS WILL BE IMPROVED SOON. MORE COMMENTS AND FASTER CODE. */
+
+mp_size
+#ifdef __STDC__
+mpn_div (mp_ptr quot_ptr,
+ mp_ptr num_ptr, mp_size num_size,
+ mp_srcptr den_ptr, mp_size den_size)
+#else
+mpn_div (quot_ptr, num_ptr, num_size, den_ptr, den_size)
+ mp_ptr quot_ptr;
+ mp_ptr num_ptr;
+ mp_size num_size;
+ mp_srcptr den_ptr;
+ mp_size den_size;
+#endif
+{
+ mp_size q_is_long = 0;
+
+ switch (den_size)
+ {
+ case 0:
+ /* We are asked to divide by zero, so go ahead and do it!
+ (To make the compiler not remove this statement, assign NUM_SIZE
+ and fall through.) */
+ num_size = 1 / den_size;
+
+ case 1:
+ {
+ mp_size i;
+ mp_limb n1, n0;
+ mp_limb d;
+
+ d = den_ptr[0];
+ i = num_size - 1;
+ n1 = num_ptr[i];
+ i--;
+
+ if (n1 >= d)
+ {
+ q_is_long = 1;
+ n1 = 0;
+ i++;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = num_ptr[i];
+ udiv_qrnnd (quot_ptr[i], n1, n1, n0, d);
+ }
+
+ num_ptr[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mp_size i;
+ mp_limb n0, n1, n2;
+ mp_limb d0, d1;
+
+ num_ptr += num_size - 2;
+ d0 = den_ptr[1];
+ d1 = den_ptr[0];
+ n0 = num_ptr[1];
+ n1 = num_ptr[0];
+
+ if (n0 >= d0)
+ {
+ q_is_long = 1;
+ n1 = n0;
+ n0 = 0;
+ num_ptr++;
+ num_size++;
+ }
+
+ for (i = num_size - den_size - 1; i >= 0; i--)
+ {
+ mp_limb q;
+ mp_limb r;
+
+ num_ptr--;
+ if (n0 == d0)
+ {
+ /* Q should be either 111..111 or 111..110. Need special
+ treatment of this rare case as normal division would
+ give overflow. */
+ q = ~0;
+
+ r = n1 + d0;
+ if (r < d0) /* Carry in the addition? */
+ {
+ n2 = num_ptr[0];
+
+ add_ssaaaa (n0, n1, r - d1, n2, 0, d1);
+ quot_ptr[i] = q;
+ continue;
+ }
+ n0 = d1 - (d1 != 0);
+ n1 = -d1;
+ }
+ else
+ {
+ udiv_qrnnd (q, r, n0, n1, d0);
+ umul_ppmm (n0, n1, d1, q);
+ }
+
+ n2 = num_ptr[0];
+ q_test:
+ if (n0 > r || (n0 == r && n1 > n2))
+ {
+ /* The estimated Q was too large. */
+ q--;
+
+ sub_ddmmss (n0, n1, n0, n1, 0, d1);
+ r += d0;
+ if (r >= d0) /* If not carry, test q again. */
+ goto q_test;
+ }
+
+ quot_ptr[i] = q;
+ sub_ddmmss (n0, n1, r, n2, n0, n1);
+ }
+ num_ptr[1] = n0;
+ num_ptr[0] = n1;
+ }
+ break;
+
+ default:
+ {
+ mp_size i;
+ mp_limb d0 = den_ptr[den_size - 1];
+ mp_limb d1 = den_ptr[den_size - 2];
+ mp_limb n0 = num_ptr[num_size - 1];
+ int ugly_hack_flag = 0;
+
+ if (n0 >= d0)
+ {
+
+ /* There's a problem with this case, which shows up later in the
+ code. q becomes 1 (and sometimes 0) the first time when
+ we've been here, and w_cy == 0 after the main do-loops below.
+ But c = num_ptr[j] reads rubbish outside the num_ptr vector!
+ Maybe I can solve this cleanly when I fix the early-end
+ optimization here in the default case. For now, I change the
+ add_back entering condition, to kludge. Leaving the stray
+ memref behind!
+
+ HACK: Added ugly_hack_flag to make it work. */
+
+ q_is_long = 1;
+ n0 = 0;
+ num_size++;
+ ugly_hack_flag = 1;
+ }
+
+ num_ptr += num_size;
+ den_ptr += den_size;
+ for (i = num_size - den_size - 1; i >= 0; i--)
+ {
+ mp_limb q;
+ mp_limb n1;
+ mp_limb w_cy;
+ mp_limb d, c;
+ mp_size j;
+
+ num_ptr--;
+ if (n0 == d0)
+ /* This might over-estimate q, but it's probably not worth
+ the extra code here to find out. */
+ q = ~0;
+ else
+ {
+ mp_limb r;
+
+ udiv_qrnnd (q, r, n0, num_ptr[-1], d0);
+ umul_ppmm (n1, n0, d1, q);
+
+ while (n1 > r || (n1 == r && n0 > num_ptr[-2]))
+ {
+ q--;
+ r += d0;
+ if (r < d0) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ w_cy = 0;
+ j = -den_size;
+ do
+ {
+ d = den_ptr[j];
+ c = num_ptr[j];
+ umul_ppmm (n1, n0, d, q);
+ n0 += w_cy;
+ w_cy = (n0 < w_cy) + n1;
+ n0 = c - n0;
+ num_ptr[j] = n0;
+ if (n0 > c)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ if (ugly_hack_flag)
+ {
+ c = 0;
+ ugly_hack_flag = 0;
+ }
+ else
+ c = num_ptr[j];
+ if (c >= w_cy)
+ goto store_q;
+ goto add_back;
+
+ do
+ {
+ d = den_ptr[j];
+ c = num_ptr[j];
+ umul_ppmm (n1, n0, d, q);
+ n0 += w_cy;
+ w_cy = (n0 < w_cy) + n1;
+ n0 = c - n0 - 1;
+ num_ptr[j] = n0;
+ if (n0 < c)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ if (ugly_hack_flag)
+ {
+ c = 0;
+ ugly_hack_flag = 0;
+ }
+ else
+ c = num_ptr[j];
+ w_cy++;
+ if (c >= w_cy)
+ goto store_q;
+
+ add_back:
+ j = -den_size;
+ do
+ {
+ d = den_ptr[j];
+ n0 = num_ptr[j] + d;
+ num_ptr[j] = n0;
+ if (n0 < d)
+ goto ab_cy_loop;
+ ab_ncy_loop:
+ j++;
+ }
+ while (j < 0);
+ abort (); /* We should always have a carry out! */
+
+ do
+ {
+ d = den_ptr[j];
+ n0 = num_ptr[j] + d + 1;
+ num_ptr[j] = n0;
+ if (n0 > d)
+ goto ab_ncy_loop;
+ ab_cy_loop:
+ j++;
+ }
+ while (j < 0);
+ q--;
+
+ store_q:
+ quot_ptr[i] = q;
+ }
+ }
+ }
+
+ return q_is_long;
+}
diff --git a/gnu/lib/libgmp/mpn_dm_1.c b/gnu/lib/libgmp/mpn_dm_1.c
new file mode 100644
index 0000000..af39124
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_dm_1.c
@@ -0,0 +1,185 @@
+/* mpn_divmod_1(quot_ptr, dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+ QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+#if UDIV_TIME > 2 * UMUL_TIME
+#undef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 1
+#endif
+
+#define udiv_qrnnd_preinv(q, r, nh, nl, d, di) \
+ do { \
+ unsigned long int _q, _ql, _r; \
+ unsigned long int _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MP_LIMB too small. */\
+ umul_ppmm (_xh, _xl, _q, (d)); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ if (_xh != 0) \
+ { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q += 1; \
+ } \
+ } \
+ if (_r >= (d)) \
+ { \
+ _r -= (d); \
+ _q += 1; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+mp_limb
+#ifdef __STDC__
+mpn_divmod_1 (mp_ptr quot_ptr,
+ mp_srcptr dividend_ptr, mp_size dividend_size,
+ unsigned long int divisor_limb)
+#else
+mpn_divmod_1 (quot_ptr, dividend_ptr, dividend_size, divisor_limb)
+ mp_ptr quot_ptr;
+ mp_srcptr dividend_ptr;
+ mp_size dividend_size;
+ unsigned long int divisor_limb;
+#endif
+{
+ mp_size i;
+ mp_limb n1, n0, r;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if (dividend_size == 0)
+ return 0;
+
+ if (UDIV_NEEDS_NORMALIZATION)
+ {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less...
+ [Don't forget to zero most sign. quotient limb!] */
+
+ /* If multiplication is much faster than division, and the
+ dividend is large, pre-invert the divisor, and use
+ only multiplications in the inner loop. */
+ if (UDIV_TIME > 2 * UMUL_TIME && dividend_size >= 4)
+ {
+ mp_limb divisor_limb_inverted;
+ int dummy;
+ /* Compute (2**64 - 2**32 * DIVISOR_LIMB) / DIVISOR_LIMB.
+ The result is an 33-bit approximation to 1/DIVISOR_LIMB,
+ with the most significant bit (weight 2**32) implicit. */
+
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if (divisor_limb << 1 == 0)
+ divisor_limb_inverted = ~0;
+ else
+ udiv_qrnnd (divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd_preinv (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ udiv_qrnnd_preinv (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else
+ {
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ }
+
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ it, or because DIVISOR_LIMB is already normalized. */
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ {
+ r = 0;
+ }
+ else
+ {
+ /* Callers expect the quotient to be DIVIDEND_SIZE limbs. Store
+ a leading zero to make that expectation come true. */
+ quot_ptr[i] = 0;
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i], r, r, n0, divisor_limb);
+ }
+ return r;
+}
diff --git a/gnu/lib/libgmp/mpn_lshift.c b/gnu/lib/libgmp/mpn_lshift.c
new file mode 100644
index 0000000..b89a736
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_lshift.c
@@ -0,0 +1,83 @@
+/* mpn_lshift -- Shift left low level.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ and store the USIZE least significant digits of the result at WP.
+ Return the bits shifted out from the most significant digit.
+
+ Argument constraints:
+ 0. U must be normalized (i.e. it's most significant digit != 0).
+ 1. 0 <= CNT < BITS_PER_MP_LIMB
+ 2. If the result is to be written over the input, WP must be >= UP.
+*/
+
+mp_limb
+#ifdef __STDC__
+mpn_lshift (mp_ptr wp,
+ mp_srcptr up, mp_size usize,
+ unsigned cnt)
+#else
+mpn_lshift (wp, up, usize, cnt)
+ mp_ptr wp;
+ mp_srcptr up;
+ mp_size usize;
+ unsigned cnt;
+#endif
+{
+ mp_limb high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mp_size i;
+ mp_limb retval;
+
+ if (usize == 0)
+ return 0;
+
+ sh_1 = cnt;
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from high end to low end, to allow specified input/output
+ overlapping. */
+ for (i = usize - 1; i >= 0; i--)
+ wp[i] = up[i];
+ }
+ return 0;
+ }
+
+ wp += 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while (--i >= 0)
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
diff --git a/gnu/lib/libgmp/mpn_mod_1.c b/gnu/lib/libgmp/mpn_mod_1.c
new file mode 100644
index 0000000..19fcefd
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_mod_1.c
@@ -0,0 +1,104 @@
+/* mpn_mod_1(dividend_ptr, dividend_size, divisor_limb) --
+ Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ Return the single-limb remainder.
+ There are no constraints on the value of the divisor.
+
+ QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+mp_limb
+#ifdef __STDC__
+mpn_mod_1 (mp_srcptr dividend_ptr, mp_size dividend_size,
+ unsigned long int divisor_limb)
+#else
+mpn_mod_1 (dividend_ptr, dividend_size, divisor_limb)
+ mp_srcptr dividend_ptr;
+ mp_size dividend_size;
+ unsigned long int divisor_limb;
+#endif
+{
+ int normalization_steps;
+ mp_size i;
+ mp_limb n1, n0, r;
+ int dummy;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if (dividend_size == 0)
+ return 0;
+
+ if (UDIV_NEEDS_NORMALIZATION)
+ {
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if (normalization_steps != 0)
+ {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MP_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ if (r == 0
+ && divisor_limb > ((n1 << normalization_steps)
+ | (dividend_ptr[dividend_size - 2] >> ...)))
+ ...one division less...
+ */
+
+ for (i = dividend_size - 2; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MP_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ it, or because DIVISOR_LIMB is already normalized. */
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if (r >= divisor_limb)
+ {
+ r = 0;
+ }
+ else
+ {
+ i--;
+ }
+
+ for (; i >= 0; i--)
+ {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+}
diff --git a/gnu/lib/libgmp/mpn_mul.c b/gnu/lib/libgmp/mpn_mul.c
new file mode 100644
index 0000000..8455f1d
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_mul.c
@@ -0,0 +1,414 @@
+/* mpn_mul -- Multiply two natural numbers.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifdef DEBUG
+#define MPN_MUL_VERIFY(res_ptr,res_size,op1_ptr,op1_size,op2_ptr,op2_size) \
+ mpn_mul_verify (res_ptr, res_size, op1_ptr, op1_size, op2_ptr, op2_size)
+
+#include <stdio.h>
+static void
+mpn_mul_verify (res_ptr, res_size, op1_ptr, op1_size, op2_ptr, op2_size)
+ mp_ptr res_ptr, op1_ptr, op2_ptr;
+ mp_size res_size, op1_size, op2_size;
+{
+ mp_ptr tmp_ptr;
+ mp_size tmp_size;
+ tmp_ptr = alloca ((op1_size + op2_size) * BYTES_PER_MP_LIMB);
+ if (op1_size >= op2_size)
+ tmp_size = mpn_mul_classic (tmp_ptr,
+ op1_ptr, op1_size, op2_ptr, op2_size);
+ else
+ tmp_size = mpn_mul_classic (tmp_ptr,
+ op2_ptr, op2_size, op1_ptr, op1_size);
+ if (tmp_size != res_size
+ || mpn_cmp (tmp_ptr, res_ptr, tmp_size) != 0)
+ {
+ fprintf (stderr, "GNU MP internal error: Wrong result in mpn_mul.\n");
+ fprintf (stderr, "op1{%d} = ", op1_size); mpn_dump (op1_ptr, op1_size);
+ fprintf (stderr, "op2{%d} = ", op2_size); mpn_dump (op2_ptr, op2_size);
+ abort ();
+ }
+}
+#else
+#define MPN_MUL_VERIFY(a,b,c,d,e,f)
+#endif
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ and v (pointed to by VP, with VSIZE limbs), and store the result at
+ PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ operands are normalized, the return value will reflect the true
+ result size (which is either USIZE + VSIZE, or USIZE + VSIZE -1).
+
+ NOTE: The space pointed to by PRODP is overwritten before finished
+ with U and V, so overlap is an error.
+
+ Argument constraints:
+ 1. USIZE >= VSIZE.
+ 2. PRODP != UP and PRODP != VP, i.e. the destination
+ must be distinct from the multiplier and the multiplicand. */
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ value which is good on most machines. */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 8
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 4. */
+#if KARATSUBA_THRESHOLD < 4
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 4
+#endif
+
+mp_size
+#ifdef __STDC__
+mpn_mul (mp_ptr prodp,
+ mp_srcptr up, mp_size usize,
+ mp_srcptr vp, mp_size vsize)
+#else
+mpn_mul (prodp, up, usize, vp, vsize)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size usize;
+ mp_srcptr vp;
+ mp_size vsize;
+#endif
+{
+ mp_size n;
+ mp_size prod_size;
+ mp_limb cy;
+
+ if (vsize < KARATSUBA_THRESHOLD)
+ {
+ /* Handle simple cases with traditional multiplication.
+
+ This is the most critical code of the entire function. All
+ multiplies rely on this, both small and huge. Small ones arrive
+ here immediately. Huge ones arrive here as this is the base case
+ for the recursive algorithm below. */
+ mp_size i, j;
+ mp_limb prod_low, prod_high;
+ mp_limb cy_limb;
+ mp_limb v_limb;
+
+ if (vsize == 0)
+ return 0;
+
+ /* Offset UP and PRODP so that the inner loop can be faster. */
+ up += usize;
+ prodp += usize;
+
+ /* Multiply by the first limb in V separately, as the result can
+ be stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if (v_limb <= 1)
+ {
+ if (v_limb == 1)
+ MPN_COPY (prodp - usize, up - usize, usize);
+ else
+ MPN_ZERO (prodp - usize, usize);
+ cy_limb = 0;
+ }
+ else
+ {
+ cy_limb = 0;
+ j = -usize;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_limb, prodp[j], prod_high, prod_low, 0, cy_limb);
+ j++;
+ }
+ while (j < 0);
+ }
+
+ prodp[0] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++)
+ {
+ v_limb = vp[i];
+ if (v_limb <= 1)
+ {
+ cy_limb = 0;
+ if (v_limb == 1)
+ cy_limb = mpn_add (prodp - usize,
+ prodp - usize, usize, up - usize, usize);
+ }
+ else
+ {
+ cy_limb = 0;
+ j = -usize;
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_limb, prod_low,
+ prod_high, prod_low, 0, cy_limb);
+ add_ssaaaa (cy_limb, prodp[j],
+ cy_limb, prod_low, 0, prodp[j]);
+ j++;
+ }
+ while (j < 0);
+ }
+
+ prodp[0] = cy_limb;
+ prodp++;
+ }
+
+ return usize + vsize - (cy_limb == 0);
+ }
+
+ n = (usize + 1) / 2;
+
+ /* Is USIZE larger than 1.5 times VSIZE? Avoid Karatsuba's algorithm. */
+ if (2 * usize > 3 * vsize)
+ {
+ /* If U has at least twice as many limbs as V. Split U in two
+ pieces, U1 and U0, such that U = U0 + U1*(2**BITS_PER_MP_LIMB)**N,
+ and recursively multiply the two pieces separately with V. */
+
+ mp_size u0_size;
+ mp_ptr tmp;
+ mp_size tmp_size;
+
+ /* V1 (the high part of V) is zero. */
+
+ /* Calculate the length of U0. It is normally equal to n, but
+ of course not for sure. */
+ for (u0_size = n; u0_size > 0 && up[u0_size - 1] == 0; u0_size--)
+ ;
+
+ /* Perform (U0 * V). */
+ if (u0_size >= vsize)
+ prod_size = mpn_mul (prodp, up, u0_size, vp, vsize);
+ else
+ prod_size = mpn_mul (prodp, vp, vsize, up, u0_size);
+ MPN_MUL_VERIFY (prodp, prod_size, up, u0_size, vp, vsize);
+
+ /* We have to zero-extend the lower partial product to n limbs,
+ since the mpn_add some lines below expect the first n limbs
+ to be well defined. (This is normally a no-op. It may
+ do something when U1 has many leading 0 limbs.) */
+ while (prod_size < n)
+ prodp[prod_size++] = 0;
+
+ tmp = (mp_ptr) alloca ((usize + vsize - n) * BYTES_PER_MP_LIMB);
+
+ /* Perform (U1 * V). Make sure the first source argument to mpn_mul
+ is not less than the second source argument. */
+ if (vsize <= usize - n)
+ tmp_size = mpn_mul (tmp, up + n, usize - n, vp, vsize);
+ else
+ tmp_size = mpn_mul (tmp, vp, vsize, up + n, usize - n);
+ MPN_MUL_VERIFY (tmp, tmp_size, up + n, usize - n, vp, vsize);
+
+ /* In this addition hides a potentially large copying of TMP. */
+ if (prod_size - n >= tmp_size)
+ cy = mpn_add (prodp + n, prodp + n, prod_size - n, tmp, tmp_size);
+ else
+ cy = mpn_add (prodp + n, tmp, tmp_size, prodp + n, prod_size - n);
+ if (cy)
+ abort (); /* prodp[prod_size] = cy; */
+
+ alloca (0);
+ return tmp_size + n;
+ }
+ else
+ {
+ /* Karatsuba's divide-and-conquer algorithm.
+
+ Split U in two pieces, U1 and U0, such that
+ U = U0 + U1*(B**n),
+ and V in V1 and V0, such that
+ V = V0 + V1*(B**n).
+
+ UV is then computed recursively using the identity
+
+ 2n n n n
+ UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ 1 1 1 0 0 1 0 0
+
+ Where B = 2**BITS_PER_MP_LIMB.
+ */
+
+ /* It's possible to decrease the temporary allocation by using the
+ prodp area for temporary storage of the middle term, and doing
+ that recursive multiplication first. (Do this later.) */
+
+ mp_size u0_size;
+ mp_size v0_size;
+ mp_size u0v0_size;
+ mp_size u1v1_size;
+ mp_ptr temp;
+ mp_size temp_size;
+ mp_size utem_size;
+ mp_size vtem_size;
+ mp_ptr ptem;
+ mp_size ptem_size;
+ int negflg;
+ mp_ptr pp;
+
+ pp = (mp_ptr) alloca (4 * n * BYTES_PER_MP_LIMB);
+
+ /* Calculate the lengths of U0 and V0. They are normally equal
+ to n, but of course not for sure. */
+ for (u0_size = n; u0_size > 0 && up[u0_size - 1] == 0; u0_size--)
+ ;
+ for (v0_size = n; v0_size > 0 && vp[v0_size - 1] == 0; v0_size--)
+ ;
+
+ /*** 1. PROD]2n..0] := U0 x V0
+ (Recursive call to mpn_mul may NOT overwrite input operands.)
+ ________________ ________________
+ |________________||____U0 x V0_____| */
+
+ if (u0_size >= v0_size)
+ u0v0_size = mpn_mul (pp, up, u0_size, vp, v0_size);
+ else
+ u0v0_size = mpn_mul (pp, vp, v0_size, up, u0_size);
+ MPN_MUL_VERIFY (pp, u0v0_size, up, u0_size, vp, v0_size);
+
+ /* Zero-extend to 2n limbs. */
+ while (u0v0_size < 2 * n)
+ pp[u0v0_size++] = 0;
+
+
+ /*** 2. PROD]4n..2n] := U1 x V1
+ (Recursive call to mpn_mul may NOT overwrite input operands.)
+ ________________ ________________
+ |_____U1 x V1____||____U0 x V0_____| */
+
+ u1v1_size = mpn_mul (pp + 2*n,
+ up + n, usize - n,
+ vp + n, vsize - n);
+ MPN_MUL_VERIFY (pp + 2*n, u1v1_size,
+ up + n, usize - n, vp + n, vsize - n);
+ prod_size = 2 * n + u1v1_size;
+
+
+ /*** 3. PTEM]2n..0] := (U1-U0) x (V0-V1)
+ (Recursive call to mpn_mul may overwrite input operands.)
+ ________________
+ |_(U1-U0)(V0-V1)_| */
+
+ temp = (mp_ptr) alloca ((2 * n + 1) * BYTES_PER_MP_LIMB);
+ if (usize - n > u0_size
+ || (usize - n == u0_size
+ && mpn_cmp (up + n, up, u0_size) >= 0))
+ {
+ utem_size = usize - n
+ + mpn_sub (temp, up + n, usize - n, up, u0_size);
+ negflg = 0;
+ }
+ else
+ {
+ utem_size = u0_size
+ + mpn_sub (temp, up, u0_size, up + n, usize - n);
+ negflg = 1;
+ }
+ if (vsize - n > v0_size
+ || (vsize - n == v0_size
+ && mpn_cmp (vp + n, vp, v0_size) >= 0))
+ {
+ vtem_size = vsize - n
+ + mpn_sub (temp + n, vp + n, vsize - n, vp, v0_size);
+ negflg ^= 1;
+ }
+ else
+ {
+ vtem_size = v0_size
+ + mpn_sub (temp + n, vp, v0_size, vp + n, vsize - n);
+ /* No change of NEGFLG. */
+ }
+ ptem = (mp_ptr) alloca (2 * n * BYTES_PER_MP_LIMB);
+ if (utem_size >= vtem_size)
+ ptem_size = mpn_mul (ptem, temp, utem_size, temp + n, vtem_size);
+ else
+ ptem_size = mpn_mul (ptem, temp + n, vtem_size, temp, utem_size);
+ MPN_MUL_VERIFY (ptem, ptem_size, temp, utem_size, temp + n, vtem_size);
+
+ /*** 4. TEMP]2n..0] := PROD]2n..0] + PROD]4n..2n]
+ ________________
+ |_____U1 x V1____|
+ ________________
+ |_____U0_x_V0____| */
+
+ cy = mpn_add (temp, pp, 2*n, pp + 2*n, u1v1_size);
+ if (cy != 0)
+ {
+ temp[2*n] = cy;
+ temp_size = 2*n + 1;
+ }
+ else
+ {
+ /* Normalize temp. pp[2*n-1] might have been zero in the
+ mpn_add call above, and thus temp might be unnormalized. */
+ for (temp_size = 2*n; temp_size > 0 && temp[temp_size - 1] == 0;
+ temp_size--)
+ ;
+ }
+
+ if (prod_size - n >= temp_size)
+ cy = mpn_add (pp + n, pp + n, prod_size - n, temp, temp_size);
+ else
+ {
+ /* This is a weird special case that should not happen (often)! */
+ cy = mpn_add (pp + n, temp, temp_size, pp + n, prod_size - n);
+ prod_size = temp_size + n;
+ }
+ if (cy != 0)
+ {
+ pp[prod_size] = cy;
+ prod_size++;
+ }
+#ifdef DEBUG
+ if (prod_size > 4 * n)
+ abort();
+#endif
+ if (negflg)
+ prod_size = prod_size
+ + mpn_sub (pp + n, pp + n, prod_size - n, ptem, ptem_size);
+ else
+ {
+ if (prod_size - n < ptem_size)
+ abort();
+ cy = mpn_add (pp + n, pp + n, prod_size - n, ptem, ptem_size);
+ if (cy != 0)
+ {
+ pp[prod_size] = cy;
+ prod_size++;
+#ifdef DEBUG
+ if (prod_size > 4 * n)
+ abort();
+#endif
+ }
+ }
+
+ MPN_COPY (prodp, pp, prod_size);
+ alloca (0);
+ return prod_size;
+ }
+}
diff --git a/gnu/lib/libgmp/mpn_rshift.c b/gnu/lib/libgmp/mpn_rshift.c
new file mode 100644
index 0000000..a4d00e8
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_rshift.c
@@ -0,0 +1,90 @@
+/* mpn_rshift -- Shift right a low-level natural-number integer.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ and store the USIZE least significant limbs of the result at WP.
+ Return the size of the result.
+
+ Argument constraints:
+ 0. U must be normalized (i.e. it's most significant limb != 0).
+ 1. 0 <= CNT < BITS_PER_MP_LIMB
+ 2. If the result is to be written over the input, WP must be <= UP.
+*/
+
+mp_size
+#ifdef __STDC__
+mpn_rshift (mp_ptr wp,
+ mp_srcptr up, mp_size usize,
+ unsigned cnt)
+#else
+mpn_rshift (wp, up, usize, cnt)
+ mp_ptr wp;
+ mp_srcptr up;
+ mp_size usize;
+ unsigned cnt;
+#endif
+{
+ mp_limb high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mp_size i;
+
+ if (usize == 0)
+ return 0;
+
+ sh_1 = cnt;
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from low end to high end, to allow specified input/output
+ overlapping. */
+ for (i = 0; i < usize; i++)
+ wp[i] = up[i];
+ }
+ return usize;
+ }
+
+ wp -= 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ high_limb = up[0];
+#if 0
+ if (cy_limb != NULL)
+ *cy_limb = high_limb << sh_2;
+#endif
+ low_limb = high_limb;
+
+ for (i = 1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ low_limb >>= sh_1;
+ if (low_limb != 0)
+ {
+ wp[i] = low_limb;
+ return usize;
+ }
+
+ return usize - 1;
+}
diff --git a/gnu/lib/libgmp/mpn_rshiftci.c b/gnu/lib/libgmp/mpn_rshiftci.c
new file mode 100644
index 0000000..b072d02
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_rshiftci.c
@@ -0,0 +1,86 @@
+/* mpn_rshiftci -- Shift a low level natural-number integer with carry in.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the right
+ and store the USIZE least significant digits of the result at WP.
+ Return the size of the result.
+
+ Argument constraints:
+ 0. U must be normalized (i.e. it's most significant digit != 0).
+ 1. 0 <= CNT < BITS_PER_MP_LIMB
+ 2. If the result is to be written over the input, WP must be <= UP.
+*/
+
+mp_size
+#ifdef __STDC__
+mpn_rshiftci (mp_ptr wp,
+ mp_srcptr up, mp_size usize,
+ unsigned cnt,
+ mp_limb carry_in)
+#else
+mpn_rshiftci (wp, up, usize, cnt, carry_in)
+ mp_ptr wp;
+ mp_srcptr up;
+ mp_size usize;
+ unsigned cnt;
+ mp_limb carry_in;
+#endif
+{
+ mp_limb high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mp_size i;
+
+ if (usize <= 0)
+ return 0;
+
+ sh_1 = cnt;
+ if (sh_1 == 0)
+ {
+ if (wp != up)
+ {
+ /* Copy from low end to high end, to allow specified input/output
+ overlapping. */
+ for (i = 0; i < usize; i++)
+ wp[i] = up[i];
+ }
+ return usize;
+ }
+
+ wp -= 1;
+ sh_2 = BITS_PER_MP_LIMB - sh_1;
+ low_limb = up[0];
+ for (i = 1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ low_limb = (low_limb >> sh_1) | (carry_in << sh_2);
+ if (low_limb != 0)
+ {
+ wp[i] = low_limb;
+ return usize;
+ }
+
+ return usize - 1;
+}
diff --git a/gnu/lib/libgmp/mpn_sqrt.c b/gnu/lib/libgmp/mpn_sqrt.c
new file mode 100644
index 0000000..7dda9e4
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_sqrt.c
@@ -0,0 +1,479 @@
+/* mpn_sqrt(root_ptr, rem_ptr, op_ptr, op_size)
+
+ Write the square root of {OP_PTR, OP_SIZE} at ROOT_PTR.
+ Write the remainder at REM_PTR, if REM_PTR != NULL.
+ Return the size of the remainder.
+ (The size of the root is always half of the size of the operand.)
+
+ OP_PTR and ROOT_PTR may not point to the same object.
+ OP_PTR and REM_PTR may point to the same object.
+
+ If REM_PTR is NULL, only the root is computed and the return value of
+ the function is 0 if OP is a perfect square, and *any* non-zero number
+ otherwise.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This code is just correct if "unsigned char" has at least 8 bits. It
+ doesn't help to use CHAR_BIT from limits.h, as the real problem is
+ the static arrays. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Square root algorithm:
+
+ 1. Shift OP (the input) to the left an even number of bits s.t. there
+ are an even number of words and either (or both) of the most
+ significant bits are set. This way, sqrt(OP) has exactly half as
+ many words as OP, and has its most significant bit set.
+
+ 2. Get a 9-bit approximation to sqrt(OP) using the pre-computed tables.
+ This approximation is used for the first single-precision
+ iterations of Newton's method, yielding a full-word approximation
+ to sqrt(OP).
+
+ 3. Perform multiple-precision Newton iteration until we have the
+ exact result. Only about half of the input operand is used in
+ this calculation, as the square root is perfectly determinable
+ from just the higher half of a number. */
+
+/* Define this macro for IEEE P854 machines with a fast sqrt instruction. */
+#if defined __GNUC__
+
+#if defined __sparc__
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrtd %1,%0" : "=f" (__sqrt_res) : "f" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#if defined __HAVE_68881__
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrtx %1,%0" : "=f" (__sqrt_res) : "f" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#if defined __hppa
+#define SQRT(a) \
+ ({ \
+ double __sqrt_res; \
+ asm ("fsqrt,dbl %1,%0" : "=fx" (__sqrt_res) : "fx" (a)); \
+ __sqrt_res; \
+ })
+#endif
+
+#endif
+
+#ifndef SQRT
+
+/* Tables for initial approximation of the square root. These are
+ indexed with bits 1-8 of the operand for which the square root is
+ calculated, where bit 0 is the most significant non-zero bit. I.e.
+ the most significant one-bit is not used, since that per definition
+ is one. Likewise, the tables don't return the highest bit of the
+ result. That bit must be inserted by or:ing the returned value with
+ 0x100. This way, we get a 9-bit approximation from 8-bit tables! */
+
+/* Table to be used for operands with an even total number of bits.
+ (Exactly as in the decimal system there are similarities between the
+ square root of numbers with the same initial digits and an even
+ difference in the total number of digits. Consider the square root
+ of 1, 10, 100, 1000, ...) */
+static unsigned char even_approx_tab[256] =
+{
+ 0x6a, 0x6a, 0x6b, 0x6c, 0x6c, 0x6d, 0x6e, 0x6e,
+ 0x6f, 0x70, 0x71, 0x71, 0x72, 0x73, 0x73, 0x74,
+ 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x79, 0x79,
+ 0x7a, 0x7b, 0x7b, 0x7c, 0x7d, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x80, 0x81, 0x81, 0x82, 0x83, 0x83, 0x84,
+ 0x85, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x89,
+ 0x8a, 0x8b, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e, 0x8f,
+ 0x8f, 0x90, 0x90, 0x91, 0x92, 0x92, 0x93, 0x94,
+ 0x94, 0x95, 0x96, 0x96, 0x97, 0x97, 0x98, 0x99,
+ 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e,
+ 0x9e, 0x9f, 0xa0, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3,
+ 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa7,
+ 0xa8, 0xa9, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xac,
+ 0xad, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1,
+ 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb5, 0xb5, 0xb6,
+ 0xb6, 0xb7, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba,
+ 0xbb, 0xbb, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf,
+ 0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc2, 0xc3, 0xc3,
+ 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc7, 0xc8,
+ 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc,
+ 0xcd, 0xce, 0xce, 0xcf, 0xcf, 0xd0, 0xd0, 0xd1,
+ 0xd1, 0xd2, 0xd3, 0xd3, 0xd4, 0xd4, 0xd5, 0xd5,
+ 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9, 0xda,
+ 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde,
+ 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe1, 0xe2, 0xe2,
+ 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6, 0xe6,
+ 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xea, 0xea, 0xeb,
+ 0xeb, 0xec, 0xec, 0xed, 0xed, 0xee, 0xee, 0xef,
+ 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2, 0xf3,
+ 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7,
+ 0xf7, 0xf8, 0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfb,
+ 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff,
+};
+
+/* Table to be used for operands with an odd total number of bits.
+ (Further comments before previous table.) */
+static unsigned char odd_approx_tab[256] =
+{
+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03,
+ 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
+ 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b,
+ 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f,
+ 0x0f, 0x10, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12,
+ 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16,
+ 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x1a,
+ 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d,
+ 0x1e, 0x1e, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x21,
+ 0x21, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24,
+ 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x27, 0x28,
+ 0x28, 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b,
+ 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2f,
+ 0x2f, 0x30, 0x30, 0x30, 0x31, 0x31, 0x32, 0x32,
+ 0x32, 0x33, 0x33, 0x34, 0x34, 0x35, 0x35, 0x35,
+ 0x36, 0x36, 0x37, 0x37, 0x37, 0x38, 0x38, 0x39,
+ 0x39, 0x39, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3c,
+ 0x3c, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3f, 0x3f,
+ 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42,
+ 0x43, 0x43, 0x43, 0x44, 0x44, 0x45, 0x45, 0x45,
+ 0x46, 0x46, 0x47, 0x47, 0x47, 0x48, 0x48, 0x49,
+ 0x49, 0x49, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4c,
+ 0x4c, 0x4c, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4f,
+ 0x4f, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x52,
+ 0x52, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x55,
+ 0x55, 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x58,
+ 0x58, 0x59, 0x59, 0x59, 0x5a, 0x5a, 0x5a, 0x5b,
+ 0x5b, 0x5b, 0x5c, 0x5c, 0x5d, 0x5d, 0x5d, 0x5e,
+ 0x5e, 0x5e, 0x5f, 0x5f, 0x60, 0x60, 0x60, 0x61,
+ 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, 0x63,
+ 0x64, 0x64, 0x65, 0x65, 0x65, 0x66, 0x66, 0x66,
+ 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, 0x69,
+};
+#endif
+
+
+mp_size
+#ifdef __STDC__
+mpn_sqrt (mp_ptr root_ptr, mp_ptr rem_ptr, mp_srcptr op_ptr, mp_size op_size)
+#else
+mpn_sqrt (root_ptr, rem_ptr, op_ptr, op_size)
+ mp_ptr root_ptr;
+ mp_ptr rem_ptr;
+ mp_srcptr op_ptr;
+ mp_size op_size;
+#endif
+{
+ /* R (root result) */
+ mp_ptr rp; /* Pointer to least significant word */
+ mp_size rsize; /* The size in words */
+
+ /* T (OP shifted to the left a.k.a. normalized) */
+ mp_ptr tp; /* Pointer to least significant word */
+ mp_size tsize; /* The size in words */
+ mp_ptr t_end_ptr; /* Pointer right beyond most sign. word */
+ mp_limb t_high0, t_high1; /* The two most significant words */
+
+ /* TT (temporary for numerator/remainder) */
+ mp_ptr ttp; /* Pointer to least significant word */
+
+ /* X (temporary for quotient in main loop) */
+ mp_ptr xp; /* Pointer to least significant word */
+ mp_size xsize; /* The size in words */
+
+ unsigned cnt;
+ mp_limb initial_approx; /* Initially made approximation */
+ mp_size tsizes[BITS_PER_MP_LIMB]; /* Successive calculation precisions */
+ mp_size tmp;
+ mp_size i;
+
+ /* If OP is zero, both results are zero. */
+ if (op_size == 0)
+ return 0;
+
+ count_leading_zeros (cnt, op_ptr[op_size - 1]);
+ tsize = op_size;
+ if ((tsize & 1) != 0)
+ {
+ cnt += BITS_PER_MP_LIMB;
+ tsize++;
+ }
+
+ rsize = tsize / 2;
+ rp = root_ptr;
+
+ /* Shift OP an even number of bits into T, such that either the most or
+ the second most significant bit is set, and such that the number of
+ words in T becomes even. This way, the number of words in R=sqrt(OP)
+ is exactly half as many as in OP, and the most significant bit of R
+ is set.
+
+ Also, the initial approximation is simplified by this up-shifted OP.
+
+ Finally, the Newtonian iteration which is the main part of this
+ program performs division by R. The fast division routine expects
+ the divisor to be "normalized" in exactly the sense of having the
+ most significant bit set. */
+
+ tp = (mp_ptr) alloca (tsize * BYTES_PER_MP_LIMB);
+
+ t_high0 = mpn_lshift (tp + cnt / BITS_PER_MP_LIMB, op_ptr, op_size,
+ (cnt & ~1) % BITS_PER_MP_LIMB);
+ if (cnt >= BITS_PER_MP_LIMB)
+ tp[0] = 0;
+
+ t_high0 = tp[tsize - 1];
+ t_high1 = tp[tsize - 2]; /* Never stray. TSIZE is >= 2. */
+
+/* Is there a fast sqrt instruction defined for this machine? */
+#ifdef SQRT
+ {
+ initial_approx = SQRT (t_high0 * 2.0
+ * ((mp_limb) 1 << (BITS_PER_MP_LIMB - 1))
+ + t_high1);
+ /* If t_high0,,t_high1 is big, the result in INITIAL_APPROX might have
+ become incorrect due to overflow in the conversion from double to
+ mp_limb above. It will typically be zero in that case, but might be
+ a small number on some machines. The most significant bit of
+ INITIAL_APPROX should be set, so that bit is a good overflow
+ indication. */
+ if ((mp_limb_signed) initial_approx >= 0)
+ initial_approx = ~0;
+ }
+#else
+ /* Get a 9 bit approximation from the tables. The tables expect to
+ be indexed with the 8 high bits right below the highest bit.
+ Also, the highest result bit is not returned by the tables, and
+ must be or:ed into the result. The scheme gives 9 bits of start
+ approximation with just 256-entry 8 bit tables. */
+
+ if ((cnt & 1) == 0)
+ {
+ /* The most sign bit of t_high0 is set. */
+ initial_approx = t_high0 >> (BITS_PER_MP_LIMB - 8 - 1);
+ initial_approx &= 0xff;
+ initial_approx = even_approx_tab[initial_approx];
+ }
+ else
+ {
+ /* The most significant bit of T_HIGH0 is unset,
+ the second most significant is set. */
+ initial_approx = t_high0 >> (BITS_PER_MP_LIMB - 8 - 2);
+ initial_approx &= 0xff;
+ initial_approx = odd_approx_tab[initial_approx];
+ }
+ initial_approx |= 0x100;
+ initial_approx <<= BITS_PER_MP_LIMB - 8 - 1;
+
+ /* Perform small precision Newtonian iterations to get a full word
+ approximation. For small operands, these iteration will make the
+ entire job. */
+ if (t_high0 == ~0)
+ initial_approx = t_high0;
+ else
+ {
+ mp_limb quot;
+
+ if (t_high0 >= initial_approx)
+ initial_approx = t_high0 + 1;
+
+ /* First get about 18 bits with pure C arithmetics. */
+ quot = t_high0 / (initial_approx >> BITS_PER_MP_LIMB/2) << BITS_PER_MP_LIMB/2;
+ initial_approx = (initial_approx + quot) / 2;
+ initial_approx |= (mp_limb) 1 << (BITS_PER_MP_LIMB - 1);
+
+ /* Now get a full word by one (or for > 36 bit machines) several
+ iterations. */
+ for (i = 16; i < BITS_PER_MP_LIMB; i <<= 1)
+ {
+ mp_limb ignored_remainder;
+
+ udiv_qrnnd (quot, ignored_remainder,
+ t_high0, t_high1, initial_approx);
+ initial_approx = (initial_approx + quot) / 2;
+ initial_approx |= (mp_limb) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+#endif
+
+ rp[0] = initial_approx;
+ rsize = 1;
+
+ xp = (mp_ptr) alloca (tsize * BYTES_PER_MP_LIMB);
+ ttp = (mp_ptr) alloca (tsize * BYTES_PER_MP_LIMB);
+
+ t_end_ptr = tp + tsize;
+
+#ifdef DEBUG
+ printf ("\n\nT = ");
+ _mp_mout (tp, tsize);
+#endif
+
+ if (tsize > 2)
+ {
+ /* Determine the successive precisions to use in the iteration. We
+ minimize the precisions, beginning with the highest (i.e. last
+ iteration) to the lowest (i.e. first iteration). */
+
+ tmp = tsize / 2;
+ for (i = 0;;i++)
+ {
+ tsize = (tmp + 1) / 2;
+ if (tmp == tsize)
+ break;
+ tsizes[i] = tsize + tmp;
+ tmp = tsize;
+ }
+
+ /* Main Newton iteration loop. For big arguments, most of the
+ time is spent here. */
+
+ /* It is possible to do a great optimization here. The successive
+ divisors in the mpn_div call below has more and more leading
+ words equal to its predecessor. Therefore the beginning of
+ each division will repeat the same work as did the last
+ division. If we could guarantee that the leading words of two
+ consecutive divisors are the same (i.e. in this case, a later
+ divisor has just more digits at the end) it would be a simple
+ matter of just using the old remainder of the last division in
+ a subsequent division, to take care of this optimization. This
+ idea would surely make a difference even for small arguments. */
+
+ /* Loop invariants:
+
+ R <= shiftdown_to_same_size(floor(sqrt(OP))) < R + 1.
+ X - 1 < shiftdown_to_same_size(floor(sqrt(OP))) <= X.
+ R <= shiftdown_to_same_size(X). */
+
+ while (--i >= 0)
+ {
+ mp_limb cy;
+#ifdef DEBUG
+ mp_limb old_least_sign_r = rp[0];
+ mp_size old_rsize = rsize;
+
+ printf ("R = ");
+ _mp_mout (rp, rsize);
+#endif
+ tsize = tsizes[i];
+
+ /* Need to copy the numerator into temporary space, as
+ mpn_div overwrites its numerator argument with the
+ remainder (which we currently ignore). */
+ MPN_COPY (ttp, t_end_ptr - tsize, tsize);
+ cy = mpn_div (xp, ttp, tsize, rp, rsize);
+ xsize = tsize - rsize;
+ cy = cy ? xp[xsize] : 0;
+
+#ifdef DEBUG
+ printf ("X =%d", cy);
+ _mp_mout (xp, xsize);
+#endif
+
+ /* Add X and R with the most significant limbs aligned,
+ temporarily ignoring at least one limb at the low end of X. */
+ tmp = xsize - rsize;
+ cy += mpn_add (xp + tmp, rp, rsize, xp + tmp, rsize);
+
+ /* If T begins with more than 2 x BITS_PER_MP_LIMB of ones, we get
+ intermediate roots that'd need an extra bit. We don't want to
+ handle that since it would make the subsequent divisor
+ non-normalized, so round such roots down to be only ones in the
+ current precision. */
+ if (cy == 2)
+ {
+ mp_size j;
+ for (j = xsize; j >= 0; j--)
+ xp[j] = ~(mp_limb)0;
+ }
+
+ /* Divide X by 2 and put the result in R. This is the new
+ approximation. Shift in the carry from the addition. */
+ rsize = mpn_rshiftci (rp, xp, xsize, 1, (mp_limb) 1);
+#ifdef DEBUG
+ if (old_least_sign_r != rp[rsize - old_rsize])
+ printf (">>>>>>>> %d: %08x, %08x <<<<<<<<\n",
+ i, old_least_sign_r, rp[rsize - old_rsize]);
+#endif
+ }
+ }
+
+#ifdef DEBUG
+ printf ("(final) R = ");
+ _mp_mout (rp, rsize);
+#endif
+
+ /* We computed the square root of OP * 2**(2*floor(cnt/2)).
+ This has resulted in R being 2**floor(cnt/2) to large.
+ Shift it down here to fix that. */
+ rsize = mpn_rshift (rp, rp, rsize, cnt/2);
+
+ /* Calculate the remainder. */
+ tsize = mpn_mul (tp, rp, rsize, rp, rsize);
+ if (op_size < tsize
+ || (op_size == tsize && mpn_cmp (op_ptr, tp, op_size) < 0))
+ {
+ /* R is too large. Decrement it. */
+ mp_limb one = 1;
+
+ tsize = tsize + mpn_sub (tp, tp, tsize, rp, rsize);
+ tsize = tsize + mpn_sub (tp, tp, tsize, rp, rsize);
+ tsize = tsize + mpn_add (tp, tp, tsize, &one, 1);
+
+ (void) mpn_sub (rp, rp, rsize, &one, 1);
+
+#ifdef DEBUG
+ printf ("(adjusted) R = ");
+ _mp_mout (rp, rsize);
+#endif
+ }
+
+ if (rem_ptr != NULL)
+ {
+ mp_size retval = op_size + mpn_sub (rem_ptr, op_ptr, op_size, tp, tsize);
+ alloca (0);
+ return retval;
+ }
+ else
+ {
+ mp_size retval = (op_size != tsize || mpn_cmp (op_ptr, tp, op_size));
+ alloca (0);
+ return retval;
+ }
+}
+
+#ifdef DEBUG
+_mp_mout (mp_srcptr p, mp_size size)
+{
+ mp_size ii;
+ for (ii = size - 1; ii >= 0; ii--)
+ printf ("%08X", p[ii]);
+
+ puts ("");
+}
+#endif
diff --git a/gnu/lib/libgmp/mpn_sub.c b/gnu/lib/libgmp/mpn_sub.c
new file mode 100644
index 0000000..3ba8afd
--- /dev/null
+++ b/gnu/lib/libgmp/mpn_sub.c
@@ -0,0 +1,162 @@
+/* mpn_sub -- Subtract two low-level natural-number integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Subtract SUB_PTR/SUB_SIZE from MIN_PTR/MIN_SIZE and store the
+ result (MIN_SIZE words) at DIF_PTR.
+
+ Return 1 if min < sub (result is negative). Otherwise, return the
+ negative difference between the number of words in dif and min.
+ (I.e. return 0 if the result has MIN_SIZE words, -1 if it has
+ MIN_SIZE - 1 words, etc.)
+
+ Argument constraint: MIN_SIZE >= SUB_SIZE.
+
+ The size of DIF can be calculated as MIN_SIZE + the return value. */
+
+mp_size
+#ifdef __STDC__
+mpn_sub (mp_ptr dif_ptr,
+ mp_srcptr min_ptr, mp_size min_size,
+ mp_srcptr sub_ptr, mp_size sub_size)
+#else
+mpn_sub (dif_ptr, min_ptr, min_size, sub_ptr, sub_size)
+ mp_ptr dif_ptr;
+ mp_srcptr min_ptr;
+ mp_size min_size;
+ mp_srcptr sub_ptr;
+ mp_size sub_size;
+#endif
+{
+ mp_limb m, s, dif;
+ mp_size j;
+
+ /* The loop counter and index J goes from some negative value to zero.
+ This way the loops are faster. Need to offset the base pointers
+ to take care of the negative indices. */
+
+ j = -sub_size;
+ if (j == 0)
+ goto sub_finished;
+
+ min_ptr -= j;
+ sub_ptr -= j;
+ dif_ptr -= j;
+
+ /* There are two do-loops, marked NON-CARRY LOOP and CARRY LOOP that
+ jump between each other. The first loop is for when the previous
+ subtraction didn't produce a carry-out; the second is for the
+ complementary case. */
+
+ /* NON-CARRY LOOP */
+ do
+ {
+ m = min_ptr[j];
+ s = sub_ptr[j];
+ dif = m - s;
+ dif_ptr[j] = dif;
+ if (dif > m)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ /* We have exhausted SUB, with no carry out. Copy remaining part of
+ MIN to DIF. */
+
+ sub_finished:
+ j = sub_size - min_size;
+
+ /* If there's no difference between the length of the operands, the
+ last words might have become zero, and re-normalization is needed. */
+ if (j == 0)
+ goto normalize;
+
+ min_ptr -= j;
+ dif_ptr -= j;
+
+ goto copy;
+
+ /* CARRY LOOP */
+ do
+ {
+ m = min_ptr[j];
+ s = sub_ptr[j];
+ dif = m - s - 1;
+ dif_ptr[j] = dif;
+ if (dif < m)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ /* We have exhausted SUB, but need to propagate carry. */
+
+ j = sub_size - min_size;
+ if (j == 0)
+ return 1; /* min < sub. Flag it to the caller */
+
+ min_ptr -= j;
+ dif_ptr -= j;
+
+ /* Propagate carry. Sooner or later the carry will cancel with a
+ non-zero word, because the minuend is normalized. Considering this,
+ there's no need to test the index J. */
+ for (;;)
+ {
+ m = min_ptr[j];
+ dif = m - 1;
+ dif_ptr[j] = dif;
+ j++;
+ if (dif < m)
+ break;
+ }
+
+ if (j == 0)
+ goto normalize;
+
+ copy:
+ /* Don't copy the remaining words of MIN to DIF if MIN_PTR and DIF_PTR
+ are equal. It would just be a no-op copying. Return 0, as the length
+ of the result equals that of the minuend. */
+ if (dif_ptr == min_ptr)
+ return 0;
+
+ do
+ {
+ dif_ptr[j] = min_ptr[j];
+ j++;
+ }
+ while (j < 0);
+ return 0;
+
+ normalize:
+ for (j = -1; j >= -min_size; j--)
+ {
+ if (dif_ptr[j] != 0)
+ return j + 1;
+ }
+
+ return -min_size;
+}
diff --git a/gnu/lib/libgmp/mpq/Makefile.in b/gnu/lib/libgmp/mpq/Makefile.in
new file mode 100644
index 0000000..f34ffb9
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/Makefile.in
@@ -0,0 +1,81 @@
+# Makefile for GNU MP/mpq functions
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+CC = gcc
+
+CFLAGS = -g -O
+AR = ar
+AR_FLAGS = rc
+SHELL = /bin/sh
+
+#### host and target specific makefile fragments come in here.
+###
+
+MPQ_SRCS = add.c canonicalize.c clear.c cmp.c cmp_ui.c div.c get_d.c \
+ get_den.c get_num.c init.c inv.c mul.c neg.c set.c set_den.c set_num.c \
+ set_si.c set_ui.c sub.c equal.c set_z.c
+MPQ_OBJS = add.o canonicalize.o clear.o cmp.o cmp_ui.o div.o get_d.o \
+ get_den.o get_num.o init.o inv.o mul.o neg.o set.o set_den.o set_num.o \
+ set_si.o set_ui.o sub.o equal.o set_z.o
+
+INCLUDES = -I. -I.. -I../mpn -I$(srcdir)/..
+
+libmpq.a: Makefile $(MPQ_OBJS)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ $(MPQ_OBJS)
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+clean mostlyclean:
+ rm -f *.o libmpq.a
+ -cd tests; $(MAKE) $@
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+ -cd tests; $(MAKE) $@
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h ../mpn/gmp-mparam.h
+
+add.o: $(srcdir)/add.c $(H)
+canonicalize.o: $(srcdir)/canonicalize.c $(H)
+clear.o: $(srcdir)/clear.c $(H)
+cmp.o: $(srcdir)/cmp.c $(H) $(srcdir)/../longlong.h
+cmp_ui.o: $(srcdir)/cmp_ui.c $(H)
+div.o: $(srcdir)/div.c $(H)
+equal.o: $(srcdir)/equal.c $(H)
+get_d.o: $(srcdir)/get_d.c $(H) $(srcdir)/../longlong.h
+get_den.o: $(srcdir)/get_den.c $(H)
+get_num.o: $(srcdir)/get_num.c $(H)
+init.o: $(srcdir)/init.c $(H)
+inv.o: $(srcdir)/inv.c $(H)
+mul.o: $(srcdir)/mul.c $(H)
+neg.o: $(srcdir)/neg.c $(H)
+set.o: $(srcdir)/set.c $(H)
+set_den.o: $(srcdir)/set_den.c $(H)
+set_num.o: $(srcdir)/set_num.c $(H)
+set_si.o: $(srcdir)/set_si.c $(H)
+set_ui.o: $(srcdir)/set_ui.c $(H)
+set_z.o: $(srcdir)/set_z.c $(H)
+sub.o: $(srcdir)/sub.c $(H)
diff --git a/gnu/lib/libgmp/mpq/add.c b/gnu/lib/libgmp/mpq/add.c
new file mode 100644
index 0000000..6b98b46
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/add.c
@@ -0,0 +1,85 @@
+/* mpq_add -- add two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_add (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_add (rop, op1, op2)
+ mpq_ptr rop;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size = ABS (op1->_mp_num._mp_size);
+ mp_size_t op1_den_size = ABS (op1->_mp_den._mp_size);
+ mp_size_t op2_num_size = ABS (op2->_mp_num._mp_size);
+ mp_size_t op2_den_size = ABS (op2->_mp_den._mp_size);
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ MPZ_TMP_INIT (gcd, MIN (op1_den_size, op2_den_size));
+ MPZ_TMP_INIT (tmp1, op1_num_size + op2_den_size);
+ MPZ_TMP_INIT (tmp2, op2_num_size + op1_den_size);
+
+ /* ROP might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of ROP when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd, &(op1->_mp_den), &(op2->_mp_den));
+ if (gcd->_mp_size > 1 || gcd->_mp_d[0] != 1)
+ {
+ mpz_t t;
+
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd);
+ mpz_mul (tmp1, &(op1->_mp_num), tmp1);
+
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd);
+ mpz_mul (tmp2, &(op2->_mp_num), tmp2);
+
+ MPZ_TMP_INIT (t, MAX (ABS (tmp1->_mp_size), ABS (tmp2->_mp_size)) + 1);
+
+ mpz_add (t, tmp1, tmp2);
+ mpz_divexact (tmp1, &(op1->_mp_den), gcd);
+ mpz_gcd (gcd, t, gcd);
+
+ mpz_divexact (&(rop->_mp_num), t, gcd);
+
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd);
+ mpz_mul (&(rop->_mp_den), tmp1, tmp2);
+ }
+ else
+ {
+ /* The common divisor is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (tmp1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_mul (tmp2, &(op2->_mp_num), &(op1->_mp_den));
+ mpz_add (&(rop->_mp_num), tmp1, tmp2);
+ mpz_mul (&(rop->_mp_den), &(op1->_mp_den), &(op2->_mp_den));
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpq/canonicalize.c b/gnu/lib/libgmp/mpq/canonicalize.c
new file mode 100644
index 0000000..901e6eb
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/canonicalize.c
@@ -0,0 +1,53 @@
+/* mpq_canonicalize(op) -- Remove common factors of the denominator and
+ numerator in OP.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_canonicalize (MP_RAT *op)
+#else
+mpq_canonicalize (op)
+ MP_RAT *op;
+#endif
+{
+ mpz_t gcd;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* ??? Dunno if the 1+ is needed. */
+ MPZ_TMP_INIT (gcd, 1 + MAX (ABS (op->_mp_num._mp_size),
+ ABS (op->_mp_den._mp_size)));
+
+ mpz_gcd (gcd, &(op->_mp_num), &(op->_mp_den));
+ mpz_divexact (&(op->_mp_num), &(op->_mp_num), gcd);
+ mpz_divexact (&(op->_mp_den), &(op->_mp_den), gcd);
+
+ if (op->_mp_den._mp_size < 0)
+ {
+ op->_mp_num._mp_size = -op->_mp_num._mp_size;
+ op->_mp_den._mp_size = -op->_mp_den._mp_size;
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpq/clear.c b/gnu/lib/libgmp/mpq/clear.c
new file mode 100644
index 0000000..2837cf2
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/clear.c
@@ -0,0 +1,37 @@
+/* mpq_clear -- free the space occupied by a MP_RAT.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_clear (MP_RAT *m)
+#else
+mpq_clear (m)
+ MP_RAT *m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_num._mp_d,
+ m->_mp_num._mp_alloc * BYTES_PER_MP_LIMB);
+ (*_mp_free_func) (m->_mp_den._mp_d,
+ m->_mp_den._mp_alloc * BYTES_PER_MP_LIMB);
+}
diff --git a/gnu/lib/libgmp/mpq/cmp.c b/gnu/lib/libgmp/mpq/cmp.c
new file mode 100644
index 0000000..fc530e3
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/cmp.c
@@ -0,0 +1,120 @@
+/* mpq_cmp(u,v) -- Compare U, V. Return postive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+int
+#if __STDC__
+mpq_cmp (const MP_RAT *op1, const MP_RAT *op2)
+#else
+mpq_cmp (op1, op2)
+ const MP_RAT *op1;
+ const MP_RAT *op2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t num2_size = op2->_mp_num._mp_size;
+ mp_size_t den2_size = op2->_mp_den._mp_size;
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size_t num1_sign;
+ int cc;
+ TMP_DECL (marker);
+
+ if (num1_size == 0)
+ return -num2_size;
+ if (num2_size == 0)
+ return num1_size;
+ if ((num1_size ^ num2_size) < 0) /* I.e. are the signs different? */
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+ num2_size = ABS (num2_size);
+
+ tmp1_size = num1_size + den2_size;
+ tmp2_size = num2_size + den1_size;
+
+ /* 1. Check to see if we can tell which operand is larger by just looking at
+ the number of limbs. */
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (tmp1_size > tmp2_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_sign;
+ if (tmp2_size > tmp1_size + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_sign;
+
+ /* 2. Same, but compare the number of significant bits. */
+ {
+ int cnt1, cnt2;
+ unsigned long int bits1, bits2;
+
+ count_leading_zeros (cnt1, op1->_mp_num._mp_d[num1_size - 1]);
+ count_leading_zeros (cnt2, op2->_mp_den._mp_d[den2_size - 1]);
+ bits1 = tmp1_size * BITS_PER_MP_LIMB - cnt1 - cnt2;
+
+ count_leading_zeros (cnt1, op2->_mp_num._mp_d[num2_size - 1]);
+ count_leading_zeros (cnt2, op1->_mp_den._mp_d[den1_size - 1]);
+ bits2 = tmp2_size * BITS_PER_MP_LIMB - cnt1 - cnt2;
+
+ if (bits1 > bits2 + 1)
+ return num1_sign;
+ if (bits2 > bits1 + 1)
+ return -num1_sign;
+ }
+
+ /* 3. Finally, cross multiply and compare. */
+
+ TMP_MARK (marker);
+ tmp1_ptr = (mp_ptr) TMP_ALLOC (tmp1_size * BYTES_PER_MP_LIMB);
+ tmp2_ptr = (mp_ptr) TMP_ALLOC (tmp2_size * BYTES_PER_MP_LIMB);
+
+ if (num1_size >= den2_size)
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ op1->_mp_num._mp_d, num1_size,
+ op2->_mp_den._mp_d, den2_size);
+ else
+ tmp1_size -= 0 == mpn_mul (tmp1_ptr,
+ op2->_mp_den._mp_d, den2_size,
+ op1->_mp_num._mp_d, num1_size);
+
+ if (num2_size >= den1_size)
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ op2->_mp_num._mp_d, num2_size,
+ op1->_mp_den._mp_d, den1_size);
+ else
+ tmp2_size -= 0 == mpn_mul (tmp2_ptr,
+ op1->_mp_den._mp_d, den1_size,
+ op2->_mp_num._mp_d, num2_size);
+
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE (marker);
+ return num1_sign < 0 ? -cc : cc;
+}
diff --git a/gnu/lib/libgmp/mpq/cmp_ui.c b/gnu/lib/libgmp/mpq/cmp_ui.c
new file mode 100644
index 0000000..bdecec5
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/cmp_ui.c
@@ -0,0 +1,84 @@
+/* mpq_cmp_ui(u,vn,vd) -- Compare U with Vn/Vd. Return positive, zero, or
+ negative based on if U > V, U == V, or U < V. Vn and Vd may have
+ common factors.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* gmp.h defines a macro for mpq_cmp_ui. */
+#undef mpq_cmp_ui
+
+int
+#if __STDC__
+mpq_cmp_ui (const MP_RAT *op1, unsigned long int num2, unsigned long int den2)
+#else
+mpq_cmp_ui (op1, num2, den2)
+ const MP_RAT *op1;
+ unsigned long int num2;
+ unsigned long int den2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size_t num1_sign;
+ mp_limb_t cy_limb;
+ int cc;
+ TMP_DECL (marker);
+
+ if (num1_size == 0)
+ return -(num2 != 0);
+ if (num1_size < 0)
+ return num1_size;
+ if (num2 == 0)
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+
+ /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
+ Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
+ if (num1_size > den1_size + 1)
+ /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
+ return num1_sign;
+ if (den1_size > num1_sign + 1)
+ /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
+ return -num1_sign;
+
+ TMP_MARK (marker);
+ tmp1_ptr = (mp_ptr) TMP_ALLOC ((num1_size + 1) * BYTES_PER_MP_LIMB);
+ tmp2_ptr = (mp_ptr) TMP_ALLOC ((den1_size + 1) * BYTES_PER_MP_LIMB);
+
+ cy_limb = mpn_mul_1 (tmp1_ptr, op1->_mp_num._mp_d, num1_size, den2);
+ tmp1_ptr[num1_size] = cy_limb;
+ tmp1_size = num1_size + (cy_limb != 0);
+
+ cy_limb = mpn_mul_1 (tmp2_ptr, op1->_mp_den._mp_d, den1_size, num2);
+ tmp2_ptr[den1_size] = cy_limb;
+ tmp2_size = den1_size + (cy_limb != 0);
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+ TMP_FREE (marker);
+ return (num1_sign < 0) ? -cc : cc;
+}
diff --git a/gnu/lib/libgmp/mpq/configure.in b/gnu/lib/libgmp/mpq/configure.in
new file mode 100644
index 0000000..b5d501c
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/configure.in
@@ -0,0 +1,12 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=tests
+srctrigger=cmp_ui.c
+srcname="GNU Multi-Precision library/mpq"
+
+# per-host:
+
+# per-target:
+
diff --git a/gnu/lib/libgmp/mpq/div.c b/gnu/lib/libgmp/mpq/div.c
new file mode 100644
index 0000000..cd1f3881
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/div.c
@@ -0,0 +1,93 @@
+/* mpq_div -- divide two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_div (mpq_ptr quot, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_div (quot, op1, op2)
+ mpq_ptr quot;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+ mpz_t numtmp;
+
+ mpz_init (gcd1);
+ mpz_init (gcd2);
+ mpz_init (tmp1);
+ mpz_init (tmp2);
+ mpz_init (numtmp);
+
+ /* QUOT might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of QUOT when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd1, &(op1->_mp_num), &(op2->_mp_num));
+ mpz_gcd (gcd2, &(op2->_mp_den), &(op1->_mp_den));
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op1->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op1->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op2->_mp_den));
+
+ mpz_mul (numtmp, tmp1, tmp2);
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op2->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op2->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op1->_mp_den));
+
+ mpz_mul (&(quot->_mp_den), tmp1, tmp2);
+
+ /* We needed to go via NUMTMP to take care of QUOT being the same
+ as either input operands. Now move NUMTMP to QUOT->_mp_num. */
+ mpz_set (&(quot->_mp_num), numtmp);
+
+ /* Keep the denominator positive. */
+ if (quot->_mp_den._mp_size < 0)
+ {
+ quot->_mp_den._mp_size = -quot->_mp_den._mp_size;
+ quot->_mp_num._mp_size = -quot->_mp_num._mp_size;
+ }
+
+ mpz_clear (numtmp);
+ mpz_clear (tmp2);
+ mpz_clear (tmp1);
+ mpz_clear (gcd2);
+ mpz_clear (gcd1);
+}
diff --git a/gnu/lib/libgmp/mpq/equal.c b/gnu/lib/libgmp/mpq/equal.c
new file mode 100644
index 0000000..2b4bb5b
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/equal.c
@@ -0,0 +1,43 @@
+/* mpq_equal(u,v) -- Compare U, V. Return non-zero if they are equal, zero
+ if they are non-equal.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpq_equal (mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_equal (op1, op2)
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mp_size_t num1_size = op1->_mp_num._mp_size;
+ mp_size_t den1_size = op1->_mp_den._mp_size;
+ mp_size_t num2_size = op2->_mp_num._mp_size;
+ mp_size_t den2_size = op2->_mp_den._mp_size;
+
+ return (num1_size == num2_size && den1_size == den2_size
+ && mpn_cmp (op1->_mp_num._mp_d, op2->_mp_num._mp_d, num1_size) == 0
+ && mpn_cmp (op1->_mp_den._mp_d, op2->_mp_den._mp_d, den1_size) == 0);
+}
diff --git a/gnu/lib/libgmp/mpq/get_d.c b/gnu/lib/libgmp/mpq/get_d.c
new file mode 100644
index 0000000..cb4e800
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/get_d.c
@@ -0,0 +1,151 @@
+/* double mpq_get_d (mpq_t src) -- Return the double approximation to SRC.
+
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+/* Algorithm:
+ 1. Develop >= n bits of src.num / src.den, where n is the number of bits
+ in a double. This (partial) division will use all bits from the
+ denominator.
+ 2. Use the remainder to determine how to round the result.
+ 3. Assign the integral result to a temporary double.
+ 4. Scale the temporary double, and return the result.
+
+ An alternative algorithm, that would be faster:
+ 0. Let n be somewhat larger than the number of significant bits in a double.
+ 1. Extract the most significant n bits of the denominator, and an equal
+ number of bits from the numerator.
+ 2. Interpret the extracted numbers as integers, call them a and b
+ respectively, and develop n bits of the fractions ((a + 1) / b) and
+ (a / (b + 1)) using mpn_divrem.
+ 3. If the computed values are identical UP TO THE POSITION WE CARE ABOUT,
+ we are done. If they are different, repeat the algorithm from step 1,
+ but first let n = n * 2.
+ 4. If we end up using all bits from the numerator and denominator, fall
+ back to the first algorithm above.
+ 5. Just to make life harder, The computation of a + 1 and b + 1 above
+ might give carry-out... Needs special handling. It might work to
+ subtract 1 in both cases instead.
+*/
+
+double
+#if __STDC__
+mpq_get_d (const MP_RAT *src)
+#else
+mpq_get_d (src)
+ const MP_RAT *src;
+#endif
+{
+ mp_ptr np, dp;
+ mp_ptr rp;
+ mp_size_t nsize = src->_mp_num._mp_size;
+ mp_size_t dsize = src->_mp_den._mp_size;
+ mp_size_t qsize, rsize;
+ mp_size_t sign_quotient = nsize ^ dsize;
+ unsigned normalization_steps;
+ mp_limb_t qlimb;
+#define N_QLIMBS (1 + (sizeof (double) + BYTES_PER_MP_LIMB-1) / BYTES_PER_MP_LIMB)
+ mp_limb_t qp[N_QLIMBS + 1];
+ TMP_DECL (marker);
+
+ if (nsize == 0)
+ return 0.0;
+
+ TMP_MARK (marker);
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+ np = src->_mp_num._mp_d;
+ dp = src->_mp_den._mp_d;
+
+ rsize = dsize + N_QLIMBS;
+ rp = (mp_ptr) TMP_ALLOC ((rsize + 1) * BYTES_PER_MP_LIMB);
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant limb. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ if (rsize > nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ nlimb = mpn_lshift (rp + (rsize - nsize),
+ np, nsize, normalization_steps);
+ }
+ else
+ {
+ nlimb = mpn_lshift (rp, np + (nsize - rsize),
+ rsize, normalization_steps);
+ }
+ if (nlimb != 0)
+ {
+ rp[rsize] = nlimb;
+ rsize++;
+ }
+ }
+ else
+ {
+ if (rsize > nsize)
+ {
+ MPN_ZERO (rp, rsize - nsize);
+ MPN_COPY (rp + (rsize - nsize), np, nsize);
+ }
+ else
+ {
+ MPN_COPY (rp, np + (nsize - rsize), rsize);
+ }
+ }
+
+ qlimb = mpn_divmod (qp, rp, rsize, dp, dsize);
+ qsize = rsize - dsize;
+ if (qlimb)
+ {
+ qp[qsize] = qlimb;
+ qsize++;
+ }
+
+ {
+ double res;
+ mp_size_t i;
+
+ res = qp[qsize - 1];
+ for (i = qsize - 2; i >= 0; i--)
+ res = res * MP_BASE_AS_DOUBLE + qp[i];
+
+ res = __gmp_scale2 (res, BITS_PER_MP_LIMB * (nsize - dsize - N_QLIMBS));
+
+ TMP_FREE (marker);
+ return sign_quotient >= 0 ? res : -res;
+ }
+}
diff --git a/gnu/lib/libgmp/mpq/get_den.c b/gnu/lib/libgmp/mpq/get_den.c
new file mode 100644
index 0000000..fc5e387
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/get_den.c
@@ -0,0 +1,41 @@
+/* mpq_get_den(den,rat_src) -- Set DEN to the denominator of RAT_SRC.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_get_den (MP_INT *den, const MP_RAT *src)
+#else
+mpq_get_den (den, src)
+ MP_INT *den;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t size = src->_mp_den._mp_size;
+
+ if (den->_mp_alloc < size)
+ _mpz_realloc (den, size);
+
+ MPN_COPY (den->_mp_d, src->_mp_den._mp_d, size);
+ den->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpq/get_num.c b/gnu/lib/libgmp/mpq/get_num.c
new file mode 100644
index 0000000..61f812f
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/get_num.c
@@ -0,0 +1,42 @@
+ /* mpq_get_num(num,rat_src) -- Set NUM to the numerator of RAT_SRC.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_get_num (MP_INT *num, const MP_RAT *src)
+#else
+mpq_get_num (num, src)
+ MP_INT *num;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t size = src->_mp_num._mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (num->_mp_alloc < abs_size)
+ _mpz_realloc (num, abs_size);
+
+ MPN_COPY (num->_mp_d, src->_mp_num._mp_d, abs_size);
+ num->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpq/init.c b/gnu/lib/libgmp/mpq/init.c
new file mode 100644
index 0000000..ae6d8b3
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/init.c
@@ -0,0 +1,40 @@
+/* mpq_init -- Make a new rational number with value 0/1.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_init (MP_RAT *x)
+#else
+mpq_init (x)
+ MP_RAT *x;
+#endif
+{
+ x->_mp_num._mp_alloc = 1;
+ x->_mp_num._mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_num._mp_size = 0;
+ x->_mp_den._mp_alloc = 1;
+ x->_mp_den._mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_den._mp_d[0] = 1;
+ x->_mp_den._mp_size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq/inv.c b/gnu/lib/libgmp/mpq/inv.c
new file mode 100644
index 0000000..745c78d
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/inv.c
@@ -0,0 +1,75 @@
+/* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC
+ with the numerator and denominator swapped.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_inv (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_inv (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t num_size = src->_mp_num._mp_size;
+ mp_size_t den_size = src->_mp_den._mp_size;
+
+ if (num_size == 0)
+ num_size = 1 / num_size; /* Divide by zero! */
+
+ if (num_size < 0)
+ {
+ num_size = -num_size;
+ den_size = -den_size;
+ }
+ dest->_mp_den._mp_size = num_size;
+ dest->_mp_num._mp_size = den_size;
+
+ /* If dest == src we may just swap the numerator and denominator, but
+ we have to ensure the new denominator is positive. */
+
+ if (dest == src)
+ {
+ mp_size_t alloc = dest->_mp_num._mp_alloc;
+ mp_ptr limb_ptr = dest->_mp_num._mp_d;
+
+ dest->_mp_num._mp_alloc = dest->_mp_den._mp_alloc;
+ dest->_mp_num._mp_d = dest->_mp_den._mp_d;
+
+ dest->_mp_den._mp_alloc = alloc;
+ dest->_mp_den._mp_d = limb_ptr;
+ }
+ else
+ {
+ den_size = ABS (den_size);
+ if (dest->_mp_num._mp_alloc < den_size)
+ _mpz_realloc (&(dest->_mp_num), den_size);
+
+ if (dest->_mp_den._mp_alloc < num_size)
+ _mpz_realloc (&(dest->_mp_den), num_size);
+
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_den._mp_d, den_size);
+ MPN_COPY (dest->_mp_den._mp_d, src->_mp_num._mp_d, num_size);
+ }
+}
diff --git a/gnu/lib/libgmp/mpq/mul.c b/gnu/lib/libgmp/mpq/mul.c
new file mode 100644
index 0000000..35f960c
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/mul.c
@@ -0,0 +1,79 @@
+/* mpq_mul -- mutiply two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_mul (mpq_ptr prod, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_mul (prod, op1, op2)
+ mpq_ptr prod;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd1, gcd2;
+ mpz_t tmp1, tmp2;
+
+ mpz_init (gcd1);
+ mpz_init (gcd2);
+ mpz_init (tmp1);
+ mpz_init (tmp2);
+
+ /* PROD might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of PROD when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_gcd (gcd2, &(op2->_mp_num), &(op1->_mp_den));
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op1->_mp_num), gcd1);
+ else
+ mpz_set (tmp1, &(op1->_mp_num));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op2->_mp_num), gcd2);
+ else
+ mpz_set (tmp2, &(op2->_mp_num));
+
+ mpz_mul (&(prod->_mp_num), tmp1, tmp2);
+
+ if (gcd1->_mp_size > 1 || gcd1->_mp_d[0] != 1)
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd1);
+ else
+ mpz_set (tmp1, &(op2->_mp_den));
+
+ if (gcd2->_mp_size > 1 || gcd2->_mp_d[0] != 1)
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd2);
+ else
+ mpz_set (tmp2, &(op1->_mp_den));
+
+ mpz_mul (&(prod->_mp_den), tmp1, tmp2);
+
+ mpz_clear (tmp2);
+ mpz_clear (tmp1);
+ mpz_clear (gcd2);
+ mpz_clear (gcd1);
+}
diff --git a/gnu/lib/libgmp/mpq/neg.c b/gnu/lib/libgmp/mpq/neg.c
new file mode 100644
index 0000000..ac54d27
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/neg.c
@@ -0,0 +1,36 @@
+/* mpq_neg(dst, src) -- Assign the negated value of SRC to DST.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_neg (MP_RAT *dst, const MP_RAT *src)
+#else
+mpq_neg (dst, src)
+ MP_RAT *dst;
+ const MP_RAT *src;
+#endif
+{
+ mpz_neg (&dst->_mp_num, &src->_mp_num);
+ mpz_set (&dst->_mp_den, &src->_mp_den);
+}
diff --git a/gnu/lib/libgmp/mpq/set.c b/gnu/lib/libgmp/mpq/set.c
new file mode 100644
index 0000000..ef85639
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set.c
@@ -0,0 +1,49 @@
+/* mpq_set(dest,src) -- Set DEST to SRC.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_set (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size_t num_size, den_size;
+ mp_size_t abs_num_size;
+
+ num_size = src->_mp_num._mp_size;
+ abs_num_size = ABS (num_size);
+ if (dest->_mp_num._mp_alloc < abs_num_size)
+ _mpz_realloc (&(dest->_mp_num), abs_num_size);
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_num._mp_d, abs_num_size);
+ dest->_mp_num._mp_size = num_size;
+
+ den_size = src->_mp_den._mp_size;
+ if (dest->_mp_den._mp_alloc < den_size)
+ _mpz_realloc (&(dest->_mp_den), den_size);
+ MPN_COPY (dest->_mp_den._mp_d, src->_mp_den._mp_d, den_size);
+ dest->_mp_den._mp_size = den_size;
+}
diff --git a/gnu/lib/libgmp/mpq/set_den.c b/gnu/lib/libgmp/mpq/set_den.c
new file mode 100644
index 0000000..4586c89
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set_den.c
@@ -0,0 +1,42 @@
+/* mpq_set_den(dest,den) -- Set the denominator of DEST from DEN.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_den (MP_RAT *dest, const MP_INT *den)
+#else
+mpq_set_den (dest, den)
+ MP_RAT *dest;
+ const MP_INT *den;
+#endif
+{
+ mp_size_t size = den->_mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (dest->_mp_den._mp_alloc < abs_size)
+ _mpz_realloc (&(dest->_mp_den), abs_size);
+
+ MPN_COPY (dest->_mp_den._mp_d, den->_mp_d, abs_size);
+ dest->_mp_den._mp_size = abs_size;
+}
diff --git a/gnu/lib/libgmp/mpq/set_num.c b/gnu/lib/libgmp/mpq/set_num.c
new file mode 100644
index 0000000..ce918ce
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set_num.c
@@ -0,0 +1,42 @@
+/* mpq_set_num(dest,num) -- Set the numerator of DEST from NUM.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_num (MP_RAT *dest, const MP_INT *num)
+#else
+mpq_set_num (dest, num)
+ MP_RAT *dest;
+ const MP_INT *num;
+#endif
+{
+ mp_size_t size = num->_mp_size;
+ mp_size_t abs_size = ABS (size);
+
+ if (dest->_mp_num._mp_alloc < abs_size)
+ _mpz_realloc (&(dest->_mp_num), abs_size);
+
+ MPN_COPY (dest->_mp_num._mp_d, num->_mp_d, abs_size);
+ dest->_mp_num._mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpq/set_si.c b/gnu/lib/libgmp/mpq/set_si.c
new file mode 100644
index 0000000..cf1f9f0
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set_si.c
@@ -0,0 +1,54 @@
+/* mpq_set_si(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_si (MP_RAT *dest, signed long int num, unsigned long int den)
+#else
+mpq_set_si (dest, num, den)
+ MP_RAT *dest;
+ signed long int num;
+ unsigned long int den;
+#endif
+{
+ unsigned long int abs_num;
+
+ abs_num = ABS (num);
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ dest->_mp_num._mp_size = 0;
+ }
+ else
+ {
+ dest->_mp_num._mp_d[0] = abs_num;
+ dest->_mp_num._mp_size = num > 0 ? 1 : -1;
+ }
+
+ dest->_mp_den._mp_d[0] = den;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq/set_ui.c b/gnu/lib/libgmp/mpq/set_ui.c
new file mode 100644
index 0000000..aaa9fc2
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set_ui.c
@@ -0,0 +1,50 @@
+/* mpq_set_ui(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_ui (MP_RAT *dest, unsigned long int num, unsigned long int den)
+#else
+mpq_set_ui (dest, num, den)
+ MP_RAT *dest;
+ unsigned long int num;
+ unsigned long int den;
+#endif
+{
+ if (num == 0)
+ {
+ /* Canonicalize 0/n to 0/1. */
+ den = 1;
+ dest->_mp_num._mp_size = 0;
+ }
+ else
+ {
+ dest->_mp_num._mp_d[0] = num;
+ dest->_mp_num._mp_size = 1;
+ }
+
+ dest->_mp_den._mp_d[0] = den;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq/set_z.c b/gnu/lib/libgmp/mpq/set_z.c
new file mode 100644
index 0000000..ca638f3
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/set_z.c
@@ -0,0 +1,46 @@
+/* mpq_set_z (dest,src) -- Set DEST to SRC.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_set_z (mpq_ptr dest, mpz_srcptr src)
+#else
+mpq_set_z (dest, src)
+ mpq_ptr dest;
+ mpz_srcptr src;
+#endif
+{
+ mp_size_t num_size;
+ mp_size_t abs_num_size;
+
+ num_size = src->_mp_size;
+ abs_num_size = ABS (num_size);
+ if (dest->_mp_num._mp_alloc < abs_num_size)
+ _mpz_realloc (&(dest->_mp_num), abs_num_size);
+ MPN_COPY (dest->_mp_num._mp_d, src->_mp_d, abs_num_size);
+ dest->_mp_num._mp_size = num_size;
+
+ dest->_mp_den._mp_d[0] = 1;
+ dest->_mp_den._mp_size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq/sub.c b/gnu/lib/libgmp/mpq/sub.c
new file mode 100644
index 0000000..9274ff8
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/sub.c
@@ -0,0 +1,85 @@
+/* mpq_sub -- subtract two rational numbers.
+
+Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpq_sub (mpq_ptr rop, mpq_srcptr op1, mpq_srcptr op2)
+#else
+mpq_sub (rop, op1, op2)
+ mpq_ptr rop;
+ mpq_srcptr op1;
+ mpq_srcptr op2;
+#endif
+{
+ mpz_t gcd;
+ mpz_t tmp1, tmp2;
+ mp_size_t op1_num_size = ABS (op1->_mp_num._mp_size);
+ mp_size_t op1_den_size = ABS (op1->_mp_den._mp_size);
+ mp_size_t op2_num_size = ABS (op2->_mp_num._mp_size);
+ mp_size_t op2_den_size = ABS (op2->_mp_den._mp_size);
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ MPZ_TMP_INIT (gcd, MIN (op1_den_size, op2_den_size));
+ MPZ_TMP_INIT (tmp1, op1_num_size + op2_den_size);
+ MPZ_TMP_INIT (tmp2, op2_num_size + op1_den_size);
+
+ /* ROP might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of ROP when we are finished
+ with the numerators of OP1 and OP2. */
+
+ mpz_gcd (gcd, &(op1->_mp_den), &(op2->_mp_den));
+ if (gcd->_mp_size > 1 || gcd->_mp_d[0] != 1)
+ {
+ mpz_t t;
+
+ mpz_divexact (tmp1, &(op2->_mp_den), gcd);
+ mpz_mul (tmp1, &(op1->_mp_num), tmp1);
+
+ mpz_divexact (tmp2, &(op1->_mp_den), gcd);
+ mpz_mul (tmp2, &(op2->_mp_num), tmp2);
+
+ MPZ_TMP_INIT (t, MAX (ABS (tmp1->_mp_size), ABS (tmp2->_mp_size)) + 1);
+
+ mpz_sub (t, tmp1, tmp2);
+ mpz_divexact (tmp1, &(op1->_mp_den), gcd);
+ mpz_gcd (gcd, t, gcd);
+
+ mpz_divexact (&(rop->_mp_num), t, gcd);
+
+ mpz_divexact (tmp2, &(op2->_mp_den), gcd);
+ mpz_mul (&(rop->_mp_den), tmp1, tmp2);
+ }
+ else
+ {
+ /* The common divisor is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (tmp1, &(op1->_mp_num), &(op2->_mp_den));
+ mpz_mul (tmp2, &(op2->_mp_num), &(op1->_mp_den));
+ mpz_sub (&(rop->_mp_num), tmp1, tmp2);
+ mpz_mul (&(rop->_mp_den), &(op1->_mp_den), &(op2->_mp_den));
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpq/tests/Makefile.in b/gnu/lib/libgmp/mpq/tests/Makefile.in
new file mode 100644
index 0000000..d7921c0
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/tests/Makefile.in
@@ -0,0 +1,48 @@
+# Makefile for mpq/tests for GNU MP
+
+srcdir = .
+
+CC = gcc
+
+TEST_LIBS = ../../libgmp.a
+INCLUDES = -I../../mpn -I$(srcdir)/../..
+CFLAGS = -g -O
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+TEST_SRCS = t-cmp.c t-cmp_ui.c t-get_d.c
+TEST_OBJS = t-cmp.o t-cmp_ui.o t-get_d.o
+TESTS = t-cmp t-cmp_ui t-get_d
+
+check: Makefile st-cmp st-cmp_ui st-get_d
+ @echo "The tests passed."
+
+st-cmp: t-cmp
+ ./t-cmp
+ touch $@
+st-cmp_ui: t-cmp_ui
+ ./t-cmp_ui
+ touch $@
+st-get_d: t-get_d
+ ./t-get_d
+ touch $@
+
+t-cmp: t-cmp.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-cmp_ui: t-cmp_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-get_d: t-get_d.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+
+t-cmp.o: $(srcdir)/t-cmp.c
+t-cmp_ui.o: $(srcdir)/t-cmp_ui.c
+t-get_d.o: $(srcdir)/t-get_d.c
+
+clean mostlyclean:
+ rm -f *.o st-* $(TESTS)
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
diff --git a/gnu/lib/libgmp/mpq/tests/configure.in b/gnu/lib/libgmp/mpq/tests/configure.in
new file mode 100644
index 0000000..5ee2138
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/tests/configure.in
@@ -0,0 +1,11 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory. For more information, check any
+# existing configure script.
+
+srctrigger=t-cmp.c
+srcname="gmp/mpq/tests"
+
+# per-host:
+
+# per-target:
diff --git a/gnu/lib/libgmp/mpq/tests/t-cmp.c b/gnu/lib/libgmp/mpq/tests/t-cmp.c
new file mode 100644
index 0000000..77e46f2
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/tests/t-cmp.c
@@ -0,0 +1,109 @@
+/* Test mpq_cmp.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#define NUM(x) (&((x)->_mp_num))
+#define DEN(x) (&((x)->_mp_den))
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+ref_mpq_cmp (a, b)
+ mpq_t a, b;
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul (ai, NUM (a), DEN (b));
+ mpz_mul (bi, NUM (b), DEN (a));
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probabilty of finding an error */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 100000;
+ int i;
+ int cc, ccref;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (b), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (b), size);
+ }
+ while (mpz_cmp_ui (DEN (b), 0) == 0);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ ccref = ref_mpq_cmp (a, b);
+ cc = mpq_cmp (a, b);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump (x)
+ mpq_t x;
+{
+ mpz_out_str (stdout, 10, NUM (x));
+ printf ("/");
+ mpz_out_str (stdout, 10, DEN (x));
+ printf ("\n");
+}
diff --git a/gnu/lib/libgmp/mpq/tests/t-cmp_ui.c b/gnu/lib/libgmp/mpq/tests/t-cmp_ui.c
new file mode 100644
index 0000000..f7b92ad
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/tests/t-cmp_ui.c
@@ -0,0 +1,102 @@
+/* Test mpq_cmp_ui.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#define NUM(x) (&((x)->_mp_num))
+#define DEN(x) (&((x)->_mp_den))
+
+#define SGN(x) ((x) < 0 ? -1 : (x) > 0 ? 1 : 0)
+
+ref_mpq_cmp_ui (a, bn, bd)
+ mpq_t a;
+ unsigned long int bn, bd;
+{
+ mpz_t ai, bi;
+ int cc;
+
+ mpz_init (ai);
+ mpz_init (bi);
+
+ mpz_mul_ui (ai, NUM (a), bd);
+ mpz_mul_ui (bi, DEN (a), bn);
+ cc = mpz_cmp (ai, bi);
+ mpz_clear (ai);
+ mpz_clear (bi);
+ return cc;
+}
+
+#ifndef SIZE
+#define SIZE 8 /* increasing this lowers the probabilty of finding an error */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a, b;
+ mp_size_t size;
+ int reps = 100000;
+ int i;
+ int cc, ccref;
+ unsigned long int bn, bd;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpq_init (a);
+ mpq_init (b);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (NUM (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (DEN (a), size);
+ }
+ while (mpz_cmp_ui (DEN (a), 0) == 0);
+
+ mpz_random2 (NUM (b), 1);
+ do
+ {
+ mpz_random2 (DEN (b), 1);
+ }
+ while (mpz_cmp_ui (DEN (b), 0) == 0);
+
+ mpq_canonicalize (a);
+ mpq_canonicalize (b);
+
+ bn = mpz_get_ui (NUM (b));
+ bd = mpz_get_ui (DEN (b));
+
+ ccref = ref_mpq_cmp_ui (a, bn, bd);
+ cc = mpq_cmp_ui (a, bn, bd);
+
+ if (SGN (ccref) != SGN (cc))
+ abort ();
+ }
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/mpq/tests/t-get_d.c b/gnu/lib/libgmp/mpq/tests/t-get_d.c
new file mode 100644
index 0000000..db4f926
--- /dev/null
+++ b/gnu/lib/libgmp/mpq/tests/t-get_d.c
@@ -0,0 +1,88 @@
+/* Test mpq_get_d
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpq_t a;
+ mp_size_t size;
+ int reps = 10000;
+ int i, j;
+ double last_d, new_d;
+ mpz_t eps;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ /* The idea here is to test the monotonousness of mpq_get_d by adding
+ numbers to the numerator and denominator. */
+
+ mpq_init (a);
+ mpz_init (eps);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_numref (a), size);
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (mpq_denref (a), size);
+ }
+ while (mpz_cmp_ui (mpq_denref (a), 0) == 0);
+
+ mpq_canonicalize (a);
+
+ last_d = mpq_get_d (a);
+ for (j = 0; j < 10; j++)
+ {
+ size = urandom () % SIZE;
+ mpz_random2 (eps, size);
+ mpz_add (mpq_numref (a), mpq_numref (a), eps);
+ mpq_canonicalize (a);
+ new_d = mpq_get_d (a);
+ if (last_d > new_d)
+ abort ();
+ last_d = new_d;
+ }
+ }
+
+ exit (0);
+}
+
+dump (x)
+ mpq_t x;
+{
+ mpz_out_str (stdout, 10, mpq_numref (x));
+ printf ("/");
+ mpz_out_str (stdout, 10, mpq_denref (x));
+ printf ("\n");
+}
diff --git a/gnu/lib/libgmp/mpq_add.c b/gnu/lib/libgmp/mpq_add.c
new file mode 100644
index 0000000..10cc12e
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_add.c
@@ -0,0 +1,85 @@
+/* mpq_add -- add two rational numbers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_add (MP_RAT *sum, const MP_RAT *a1, const MP_RAT *a2)
+#else
+mpq_add (sum, a1, a2)
+ MP_RAT *sum;
+ const MP_RAT *a1;
+ const MP_RAT *a2;
+#endif
+{
+ MP_INT gcd1, gcd2;
+ MP_INT tmp1, tmp2;
+
+ mpz_init (&gcd1);
+ mpz_init (&gcd2);
+ mpz_init (&tmp1);
+ mpz_init (&tmp2);
+
+ /* SUM might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of SUM when we are finished
+ with the numerators of A1 and A2. */
+
+ mpz_gcd (&gcd1, &(a1->den), &(a2->den));
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ {
+ MP_INT t;
+
+ mpz_init (&t);
+
+ mpz_div (&tmp1, &(a2->den), &gcd1);
+ mpz_mul (&tmp1, &(a1->num), &tmp1);
+
+ mpz_div (&tmp2, &(a1->den), &gcd1);
+ mpz_mul (&tmp2, &(a2->num), &tmp2);
+
+ mpz_add (&t, &tmp1, &tmp2);
+ mpz_gcd (&gcd2, &t, &gcd1);
+
+ mpz_div (&(sum->num), &t, &gcd2);
+
+ mpz_div (&tmp1, &(a1->den), &gcd1);
+ mpz_div (&tmp2, &(a2->den), &gcd2);
+ mpz_mul (&(sum->den), &tmp1, &tmp2);
+
+ mpz_clear (&t);
+ }
+ else
+ {
+ /* The common divisior is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (&tmp1, &(a1->num), &(a2->den));
+ mpz_mul (&tmp2, &(a2->num), &(a1->den));
+ mpz_add (&(sum->num), &tmp1, &tmp2);
+ mpz_mul (&(sum->den), &(a1->den), &(a2->den));
+ }
+
+ mpz_clear (&tmp2);
+ mpz_clear (&tmp1);
+ mpz_clear (&gcd2);
+ mpz_clear (&gcd1);
+}
diff --git a/gnu/lib/libgmp/mpq_clear.c b/gnu/lib/libgmp/mpq_clear.c
new file mode 100644
index 0000000..3266463
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_clear.c
@@ -0,0 +1,34 @@
+/* mpq_clear -- free the space occupied by a MP_RAT.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_clear (MP_RAT *m)
+#else
+mpq_clear (m)
+ MP_RAT *m;
+#endif
+{
+ (*_mp_free_func) (m->num.d, m->num.alloc * BYTES_PER_MP_LIMB);
+ (*_mp_free_func) (m->den.d, m->den.alloc * BYTES_PER_MP_LIMB);
+}
diff --git a/gnu/lib/libgmp/mpq_cmp.c b/gnu/lib/libgmp/mpq_cmp.c
new file mode 100644
index 0000000..fd6abcc
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_cmp.c
@@ -0,0 +1,76 @@
+/* mpq_cmp(u,v) -- Compare U, V. Return positive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#ifdef __STDC__
+mpq_cmp (const MP_RAT *op1, const MP_RAT *op2)
+#else
+mpq_cmp (op1, op2)
+ const MP_RAT *op1;
+ const MP_RAT *op2;
+#endif
+{
+ mp_size num1_size = op1->num.size;
+ mp_size den1_size = op1->den.size;
+ mp_size num2_size = op2->num.size;
+ mp_size den2_size = op2->den.size;
+ mp_size tmp1_size, tmp2_size;
+ mp_ptr tmp1_ptr, tmp2_ptr;
+ mp_size num1_sign;
+ int cc;
+
+ if (num1_size == 0)
+ return -num2_size;
+ if (num2_size == 0)
+ return num1_size;
+ if ((num1_size ^ num2_size) < 0) /* I.e. are the signs different? */
+ return num1_size;
+
+ num1_sign = num1_size;
+ num1_size = ABS (num1_size);
+ num2_size = ABS (num2_size);
+
+ tmp1_size = num1_size + den2_size;
+ tmp2_size = num2_size + den1_size;
+
+ if (tmp1_size != tmp2_size)
+ return (tmp1_size - tmp2_size) ^ num1_sign;
+
+ tmp1_ptr = (mp_ptr) alloca (tmp1_size * BYTES_PER_MP_LIMB);
+ tmp2_ptr = (mp_ptr) alloca (tmp2_size * BYTES_PER_MP_LIMB);
+
+ tmp1_size = (num1_size >= den2_size)
+ ? mpn_mul (tmp1_ptr, op1->num.d, num1_size, op2->den.d, den2_size)
+ : mpn_mul (tmp1_ptr, op2->den.d, den2_size, op1->num.d, num1_size);
+
+ tmp2_size = (num2_size >= den1_size)
+ ? mpn_mul (tmp2_ptr, op2->num.d, num2_size, op1->den.d, den1_size)
+ : mpn_mul (tmp2_ptr, op1->den.d, den1_size, op2->num.d, num2_size);
+
+ cc = tmp1_size - tmp2_size != 0
+ ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
+
+ alloca (0);
+ return (num1_sign < 0) ? -cc : cc;
+}
diff --git a/gnu/lib/libgmp/mpq_div.c b/gnu/lib/libgmp/mpq_div.c
new file mode 100644
index 0000000..f08aa27
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_div.c
@@ -0,0 +1,92 @@
+/* mpq_div -- divide two rational numbers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_div (MP_RAT *quot, const MP_RAT *dividend, const MP_RAT *divisor)
+#else
+mpq_div (quot, dividend, divisor)
+ MP_RAT *quot;
+ const MP_RAT *dividend;
+ const MP_RAT *divisor;
+#endif
+{
+ MP_INT gcd1, gcd2;
+ MP_INT tmp1, tmp2;
+ MP_INT numtmp;
+
+ mpz_init (&gcd1);
+ mpz_init (&gcd2);
+ mpz_init (&tmp1);
+ mpz_init (&tmp2);
+ mpz_init (&numtmp);
+
+ /* QUOT might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of QUOT when we are finished
+ with the numerators of DIVIDEND and DIVISOR. */
+
+ mpz_gcd (&gcd1, &(dividend->num), &(divisor->num));
+ mpz_gcd (&gcd2, &(divisor->den), &(dividend->den));
+
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ mpz_div (&tmp1, &(dividend->num), &gcd1);
+ else
+ mpz_set (&tmp1, &(dividend->num));
+
+ if (gcd2.size > 1 || gcd2.d[0] != 1)
+ mpz_div (&tmp2, &(divisor->den), &gcd2);
+ else
+ mpz_set (&tmp2, &(divisor->den));
+
+ mpz_mul (&numtmp, &tmp1, &tmp2);
+
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ mpz_div (&tmp1, &(divisor->num), &gcd1);
+ else
+ mpz_set (&tmp1, &(divisor->num));
+
+ if (gcd2.size > 1 || gcd2.d[0] != 1)
+ mpz_div (&tmp2, &(dividend->den), &gcd2);
+ else
+ mpz_set (&tmp2, &(dividend->den));
+
+ mpz_mul (&(quot->den), &tmp1, &tmp2);
+
+ /* We needed to go via NUMTMP to take care of QUOT being the same
+ as either input operands. Now move NUMTMP to QUOT->NUM. */
+ mpz_set (&(quot->num), &numtmp);
+
+ /* Keep the denominator positive. */
+ if (quot->den.size < 0)
+ {
+ quot->den.size = -quot->den.size;
+ quot->num.size = -quot->num.size;
+ }
+
+ mpz_clear (&numtmp);
+ mpz_clear (&tmp2);
+ mpz_clear (&tmp1);
+ mpz_clear (&gcd2);
+ mpz_clear (&gcd1);
+}
diff --git a/gnu/lib/libgmp/mpq_get_den.c b/gnu/lib/libgmp/mpq_get_den.c
new file mode 100644
index 0000000..12b9fe2
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_get_den.c
@@ -0,0 +1,40 @@
+/* mpq_get_den(den,rat_src) -- Set DEN to the denominator of RAT_SRC.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_get_den (MP_INT *den, const MP_RAT *src)
+#else
+mpq_get_den (den, src)
+ MP_INT *den;
+ const MP_RAT *src;
+#endif
+{
+ mp_size size = src->den.size;
+
+ if (den->alloc < size)
+ _mpz_realloc (den, size);
+
+ MPN_COPY (den->d, src->den.d, size);
+ den->size = size;
+}
diff --git a/gnu/lib/libgmp/mpq_get_num.c b/gnu/lib/libgmp/mpq_get_num.c
new file mode 100644
index 0000000..4240652
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_get_num.c
@@ -0,0 +1,41 @@
+ /* mpq_get_num(num,rat_src) -- Set NUM to the numerator of RAT_SRC.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_get_num (MP_INT *num, const MP_RAT *src)
+#else
+mpq_get_num (num, src)
+ MP_INT *num;
+ const MP_RAT *src;
+#endif
+{
+ mp_size size = src->num.size;
+ mp_size abs_size = ABS (size);
+
+ if (num->alloc < abs_size)
+ _mpz_realloc (num, abs_size);
+
+ MPN_COPY (num->d, src->num.d, abs_size);
+ num->size = size;
+}
diff --git a/gnu/lib/libgmp/mpq_init.c b/gnu/lib/libgmp/mpq_init.c
new file mode 100644
index 0000000..fcb0bd2
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_init.c
@@ -0,0 +1,39 @@
+/* mpq_init -- Make a new rational number with value 0/1.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_init (MP_RAT *x)
+#else
+mpq_init (x)
+ MP_RAT *x;
+#endif
+{
+ x->num.alloc = 1;
+ x->num.d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->num.alloc);
+ x->num.size = 0;
+ x->den.alloc = 1;
+ x->den.d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->den.alloc);
+ x->den.d[0] = 1;
+ x->den.size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq_inv.c b/gnu/lib/libgmp/mpq_inv.c
new file mode 100644
index 0000000..07fcaa1
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_inv.c
@@ -0,0 +1,74 @@
+/* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC
+ with the numerator and denominator swapped.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_inv (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_inv (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size num_size = src->num.size;
+ mp_size den_size = src->den.size;
+
+ if (num_size == 0)
+ num_size = 1 / num_size; /* Divide by zero! */
+
+ if (num_size < 0)
+ {
+ num_size = -num_size;
+ den_size = -den_size;
+ }
+ dest->den.size = num_size;
+ dest->num.size = den_size;
+
+ /* If dest == src we may just swap the numerator and denominator, but
+ we have to ensure the new denominator is positive. */
+
+ if (dest == src)
+ {
+ mp_size alloc = dest->num.alloc;
+ mp_ptr limb_ptr = dest->num.d;
+
+ dest->num.alloc = dest->den.alloc;
+ dest->num.d = dest->den.d;
+
+ dest->den.alloc = alloc;
+ dest->den.d = limb_ptr;
+ }
+ else
+ {
+ den_size = ABS (den_size);
+ if (dest->num.alloc < den_size)
+ _mpz_realloc (&(dest->num), den_size);
+
+ if (dest->den.alloc < num_size)
+ _mpz_realloc (&(dest->den), num_size);
+
+ MPN_COPY (dest->num.d, src->den.d, den_size);
+ MPN_COPY (dest->den.d, src->num.d, num_size);
+ }
+}
diff --git a/gnu/lib/libgmp/mpq_mul.c b/gnu/lib/libgmp/mpq_mul.c
new file mode 100644
index 0000000..003d6ca
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_mul.c
@@ -0,0 +1,78 @@
+/* mpq_mul -- mutiply two rational numbers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_mul (MP_RAT *prod, const MP_RAT *m1, const MP_RAT *m2)
+#else
+mpq_mul (prod, m1, m2)
+ MP_RAT *prod;
+ const MP_RAT *m1;
+ const MP_RAT *m2;
+#endif
+{
+ MP_INT gcd1, gcd2;
+ MP_INT tmp1, tmp2;
+
+ mpz_init (&gcd1);
+ mpz_init (&gcd2);
+ mpz_init (&tmp1);
+ mpz_init (&tmp2);
+
+ /* PROD might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of PROD when we are finished
+ with the numerators of M1 and M1. */
+
+ mpz_gcd (&gcd1, &(m1->num), &(m2->den));
+ mpz_gcd (&gcd2, &(m2->num), &(m1->den));
+
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ mpz_div (&tmp1, &(m1->num), &gcd1);
+ else
+ mpz_set (&tmp1, &(m1->num));
+
+ if (gcd2.size > 1 || gcd2.d[0] != 1)
+ mpz_div (&tmp2, &(m2->num), &gcd2);
+ else
+ mpz_set (&tmp2, &(m2->num));
+
+ mpz_mul (&(prod->num), &tmp1, &tmp2);
+
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ mpz_div (&tmp1, &(m2->den), &gcd1);
+ else
+ mpz_set (&tmp1, &(m2->den));
+
+ if (gcd2.size > 1 || gcd2.d[0] != 1)
+ mpz_div (&tmp2, &(m1->den), &gcd2);
+ else
+ mpz_set (&tmp2, &(m1->den));
+
+ mpz_mul (&(prod->den), &tmp1, &tmp2);
+
+ mpz_clear (&tmp2);
+ mpz_clear (&tmp1);
+ mpz_clear (&gcd2);
+ mpz_clear (&gcd1);
+}
diff --git a/gnu/lib/libgmp/mpq_neg.c b/gnu/lib/libgmp/mpq_neg.c
new file mode 100644
index 0000000..2141e25
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_neg.c
@@ -0,0 +1,35 @@
+/* mpq_neg(dst, src) -- Assign the negated value of SRC to DST.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_neg (MP_RAT *dst, const MP_RAT *src)
+#else
+mpq_neg (dst, src)
+ MP_RAT *dst;
+ const MP_RAT *src;
+#endif
+{
+ mpz_neg (&dst->num, &src->num);
+ mpz_set (&dst->den, &src->den);
+}
diff --git a/gnu/lib/libgmp/mpq_set.c b/gnu/lib/libgmp/mpq_set.c
new file mode 100644
index 0000000..1d0cf3e
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_set.c
@@ -0,0 +1,48 @@
+/* mpq_set(dest,src) -- Set DEST to SRC.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_set (MP_RAT *dest, const MP_RAT *src)
+#else
+mpq_set (dest, src)
+ MP_RAT *dest;
+ const MP_RAT *src;
+#endif
+{
+ mp_size num_size, den_size;
+ mp_size abs_num_size;
+
+ num_size = src->num.size;
+ abs_num_size = ABS (num_size);
+ if (dest->num.alloc < abs_num_size)
+ _mpz_realloc (&(dest->num), abs_num_size);
+ MPN_COPY (dest->num.d, src->num.d, abs_num_size);
+ dest->num.size = num_size;
+
+ den_size = src->den.size;
+ if (dest->den.alloc < den_size)
+ _mpz_realloc (&(dest->den), den_size);
+ MPN_COPY (dest->den.d, src->den.d, den_size);
+ dest->den.size = den_size;
+}
diff --git a/gnu/lib/libgmp/mpq_set_den.c b/gnu/lib/libgmp/mpq_set_den.c
new file mode 100644
index 0000000..d532f1a
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_set_den.c
@@ -0,0 +1,46 @@
+/* mpq_set_den(dest,den) -- Set the denominator of DEST from DEN.
+ If DEN < 0 change the sign of the numerator of DEST.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_set_den (MP_RAT *dest, const MP_INT *den)
+#else
+mpq_set_den (dest, den)
+ MP_RAT *dest;
+ const MP_INT *den;
+#endif
+{
+ mp_size size = den->size;
+ mp_size abs_size = ABS (size);
+
+ if (dest->den.alloc < abs_size)
+ _mpz_realloc (&(dest->den), abs_size);
+
+ MPN_COPY (dest->den.d, den->d, abs_size);
+ dest->den.size = abs_size;
+
+ /* The denominator is always positive; move the sign to the numerator. */
+ if (size < 0)
+ dest->num.size = -dest->num.size;
+}
diff --git a/gnu/lib/libgmp/mpq_set_num.c b/gnu/lib/libgmp/mpq_set_num.c
new file mode 100644
index 0000000..609f16b
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_set_num.c
@@ -0,0 +1,41 @@
+/* mpq_set_num(dest,num) -- Set the numerator of DEST from NUM.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_set_num (MP_RAT *dest, const MP_INT *num)
+#else
+mpq_set_num (dest, num)
+ MP_RAT *dest;
+ const MP_INT *num;
+#endif
+{
+ mp_size size = num->size;
+ mp_size abs_size = ABS (size);
+
+ if (dest->num.alloc < abs_size)
+ _mpz_realloc (&(dest->num), abs_size);
+
+ MPN_COPY (dest->num.d, num->d, abs_size);
+ dest->num.size = size;
+}
diff --git a/gnu/lib/libgmp/mpq_set_si.c b/gnu/lib/libgmp/mpq_set_si.c
new file mode 100644
index 0000000..f108b6c
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_set_si.c
@@ -0,0 +1,76 @@
+/* mpq_set_si(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static unsigned long int
+gcd (x, y)
+ unsigned long int x, y;
+{
+ for (;;)
+ {
+ x = x % y;
+ if (x == 0)
+ return y;
+ y = y % x;
+ if (y == 0)
+ return x;
+ }
+}
+
+void
+#ifdef __STDC__
+mpq_set_si (MP_RAT *dest, signed long int num, unsigned long int den)
+#else
+mpq_set_si (dest, num, den)
+ MP_RAT *dest;
+ signed long int num;
+ unsigned long int den;
+#endif
+{
+ unsigned long int g;
+ unsigned long int abs_num;
+
+ abs_num = ABS (num);
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/d to 0/1. */
+ den = 1;
+ dest->num.size = 0;
+ }
+ else
+ {
+ /* Remove any common factor in NUM and DEN. */
+ /* Pass DEN as the second argument to gcd, in order to make the
+ gcd function divide by zero if DEN is zero. */
+ g = gcd (abs_num, den);
+ abs_num /= g;
+ den /= g;
+
+ dest->num.d[0] = abs_num;
+ dest->num.size = num > 0 ? 1 : -1;
+ }
+
+ dest->den.d[0] = den;
+ dest->den.size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq_set_ui.c b/gnu/lib/libgmp/mpq_set_ui.c
new file mode 100644
index 0000000..54b69ee
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_set_ui.c
@@ -0,0 +1,73 @@
+/* mpq_set_ui(dest,ulong_num,ulong_den) -- Set DEST to the retional number
+ ULONG_NUM/ULONG_DEN.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static unsigned long int
+gcd (x, y)
+ unsigned long int x, y;
+{
+ for (;;)
+ {
+ x = x % y;
+ if (x == 0)
+ return y;
+ y = y % x;
+ if (y == 0)
+ return x;
+ }
+}
+
+void
+#ifdef __STDC__
+mpq_set_ui (MP_RAT *dest, unsigned long int num, unsigned long int den)
+#else
+mpq_set_ui (dest, num, den)
+ MP_RAT *dest;
+ unsigned long int num;
+ unsigned long int den;
+#endif
+{
+ unsigned long int g;
+
+ if (num == 0)
+ {
+ /* Canonicalize 0/n to 0/1. */
+ den = 1;
+ dest->num.size = 0;
+ }
+ else
+ {
+ /* Remove any common factor in NUM and DEN. */
+ /* Pass DEN as the second argument to gcd, in order to make the
+ gcd function divide by zero if DEN is zero. */
+ g = gcd (num, den);
+ num /= g;
+ den /= g;
+
+ dest->num.d[0] = num;
+ dest->num.size = 1;
+ }
+
+ dest->den.d[0] = den;
+ dest->den.size = 1;
+}
diff --git a/gnu/lib/libgmp/mpq_sub.c b/gnu/lib/libgmp/mpq_sub.c
new file mode 100644
index 0000000..a512705
--- /dev/null
+++ b/gnu/lib/libgmp/mpq_sub.c
@@ -0,0 +1,85 @@
+/* mpq_sub -- subtract two rational numbers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpq_sub (MP_RAT *dif, const MP_RAT *min, const MP_RAT *sub)
+#else
+mpq_sub (dif, min, sub)
+ MP_RAT *dif;
+ const MP_RAT *min;
+ const MP_RAT *sub;
+#endif
+{
+ MP_INT gcd1, gcd2;
+ MP_INT tmp1, tmp2;
+
+ mpz_init (&gcd1);
+ mpz_init (&gcd2);
+ mpz_init (&tmp1);
+ mpz_init (&tmp2);
+
+ /* DIF might be identical to either operand, so don't store the
+ result there until we are finished with the input operands. We
+ dare to overwrite the numerator of DIF when we are finished
+ with the numerators of MIN and SUB. */
+
+ mpz_gcd (&gcd1, &(min->den), &(sub->den));
+ if (gcd1.size > 1 || gcd1.d[0] != 1)
+ {
+ MP_INT t;
+
+ mpz_init (&t);
+
+ mpz_div (&tmp1, &(sub->den), &gcd1);
+ mpz_mul (&tmp1, &(min->num), &tmp1);
+
+ mpz_div (&tmp2, &(min->den), &gcd1);
+ mpz_mul (&tmp2, &(sub->num), &tmp2);
+
+ mpz_sub (&t, &tmp1, &tmp2);
+ mpz_gcd (&gcd2, &t, &gcd1);
+
+ mpz_div (&(dif->num), &t, &gcd2);
+
+ mpz_div (&tmp1, &(min->den), &gcd1);
+ mpz_div (&tmp2, &(sub->den), &gcd2);
+ mpz_mul (&(dif->den), &tmp1, &tmp2);
+
+ mpz_clear (&t);
+ }
+ else
+ {
+ /* The common divisior is 1. This is the case (for random input) with
+ probability 6/(pi**2). */
+ mpz_mul (&tmp1, &(min->num), &(sub->den));
+ mpz_mul (&tmp2, &(sub->num), &(min->den));
+ mpz_sub (&(dif->num), &tmp1, &tmp2);
+ mpz_mul (&(dif->den), &(min->den), &(sub->den));
+ }
+
+ mpz_clear (&tmp2);
+ mpz_clear (&tmp1);
+ mpz_clear (&gcd2);
+ mpz_clear (&gcd1);
+}
diff --git a/gnu/lib/libgmp/mpz/Makefile.in b/gnu/lib/libgmp/mpz/Makefile.in
new file mode 100644
index 0000000..497f09c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/Makefile.in
@@ -0,0 +1,180 @@
+# Makefile for GNU MP/mpz functions
+# Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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 MP 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.
+
+srcdir = .
+
+CC = gcc
+
+# If you cross compile on a machine with the same sizes of the integral
+# types ("int", "long int", "short int", and "char") define this as the
+# local compiler. Otherwise, you need to look for the uses of LOCAL_CC below,
+# and handle those cases manually.
+LOCAL_CC = $(CC)
+CFLAGS = -g -O
+AR = ar
+AR_FLAGS = rc
+SHELL = /bin/sh
+
+#### host and target specific makefile fragments come in here.
+###
+
+MPZ_SRCS = init.c set.c set_ui.c set_si.c set_str.c set_d.c set_f.c set_q.c \
+ iset.c iset_ui.c iset_si.c iset_str.c iset_d.c clear.c \
+ get_ui.c get_si.c get_str.c get_d.c size.c sizeinbase.c \
+ add.c add_ui.c sub.c sub_ui.c mul.c mul_ui.c \
+ gcd.c gcd_ui.c gcdext.c sqrt.c sqrtrem.c powm.c powm_ui.c \
+ cmp.c cmp_ui.c cmp_si.c mul_2exp.c fdiv_q_2exp.c fdiv_r_2exp.c \
+ tdiv_q_2exp.c tdiv_r_2exp.c abs.c neg.c com.c and.c ior.c \
+ inp_raw.c inp_str.c out_raw.c out_str.c \
+ perfsqr.c random.c random2.c pow_ui.c ui_pow_ui.c setbit.c \
+ clrbit.c fac_ui.c pprime_p.c realloc.c getlimbn.c popcount.c hamdist.c \
+ cdiv_qr.c cdiv_q.c cdiv_r.c cdiv_qr_ui.c cdiv_q_ui.c cdiv_r_ui.c cdiv_ui.c \
+ fdiv_qr.c fdiv_q.c fdiv_r.c fdiv_qr_ui.c fdiv_q_ui.c fdiv_r_ui.c fdiv_ui.c \
+ tdiv_qr.c tdiv_q.c tdiv_r.c tdiv_qr_ui.c tdiv_q_ui.c tdiv_r_ui.c \
+ mod.c divexact.c array_init.c scan0.c scan1.c \
+ jacobi.c legendre.c invert.c
+MPZ_OBJS = init.o set.o set_ui.o set_si.o set_str.o set_d.o set_f.o set_q.o \
+ iset.o iset_ui.o iset_si.o iset_str.o iset_d.o clear.o \
+ get_ui.o get_si.o get_str.o get_d.o size.o sizeinbase.o \
+ add.o add_ui.o sub.o sub_ui.o mul.o mul_ui.o \
+ gcd.o gcd_ui.o gcdext.o sqrt.o sqrtrem.o powm.o powm_ui.o \
+ cmp.o cmp_ui.o cmp_si.o mul_2exp.o fdiv_q_2exp.o fdiv_r_2exp.o \
+ tdiv_q_2exp.o tdiv_r_2exp.o abs.o neg.o com.o and.o ior.o \
+ inp_raw.o inp_str.o out_raw.o out_str.o \
+ perfsqr.o random.o random2.o pow_ui.o ui_pow_ui.o setbit.o \
+ clrbit.o fac_ui.o pprime_p.o realloc.o getlimbn.o popcount.o hamdist.o \
+ cdiv_qr.o cdiv_q.o cdiv_r.o cdiv_qr_ui.o cdiv_q_ui.o cdiv_r_ui.o cdiv_ui.o \
+ fdiv_qr.o fdiv_q.o fdiv_r.o fdiv_qr_ui.o fdiv_q_ui.o fdiv_r_ui.o fdiv_ui.o \
+ tdiv_qr.o tdiv_q.o tdiv_r.o tdiv_qr_ui.o tdiv_q_ui.o tdiv_r_ui.o \
+ mod.o divexact.o array_init.o scan0.o scan1.o \
+ jacobi.o legendre.o invert.o
+
+INCLUDES = -I. -I.. -I../mpn -I$(srcdir)/..
+
+libmpz.a: Makefile $(MPZ_OBJS)
+ rm -f $@
+ $(AR) $(AR_FLAGS) $@ $(MPZ_OBJS)
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+clean mostlyclean:
+ rm -f *.o libmpz.a
+ -cd tests; $(MAKE) $@
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+ -cd tests; $(MAKE) $@
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
+
+H = $(srcdir)/../gmp.h $(srcdir)/../gmp-impl.h ../mpn/gmp-mparam.h
+
+abs.o: $(srcdir)/abs.c $(H)
+add.o: $(srcdir)/add.c $(H)
+add_ui.o: $(srcdir)/add_ui.c $(H)
+and.o: $(srcdir)/and.c $(H)
+array_init.o: $(srcdir)/array_init.c $(H)
+cdiv_q.o: $(srcdir)/cdiv_q.c $(H)
+cdiv_q_ui.o: $(srcdir)/cdiv_q_ui.c $(H)
+cdiv_qr.o: $(srcdir)/cdiv_qr.c $(H)
+cdiv_qr_ui.o: $(srcdir)/cdiv_qr_ui.c $(H)
+cdiv_r.o: $(srcdir)/cdiv_r.c $(H)
+cdiv_r_ui.o: $(srcdir)/cdiv_r_ui.c $(H)
+cdiv_ui.o: $(srcdir)/cdiv_ui.c $(H)
+clear.o: $(srcdir)/clear.c $(H)
+clrbit.o: $(srcdir)/clrbit.c $(H)
+cmp.o: $(srcdir)/cmp.c $(H)
+cmp_si.o: $(srcdir)/cmp_si.c $(H)
+cmp_ui.o: $(srcdir)/cmp_ui.c $(H)
+com.o: $(srcdir)/com.c $(H)
+fdiv_q_2exp.o: $(srcdir)/fdiv_q_2exp.c $(H)
+fdiv_r_2exp.o: $(srcdir)/fdiv_r_2exp.c $(H)
+divexact.o: $(srcdir)/divexact.c $(H) $(srcdir)/../longlong.h
+fac_ui.o: $(srcdir)/fac_ui.c $(H) $(srcdir)/../longlong.h
+fdiv_q.o: $(srcdir)/fdiv_q.c $(H)
+fdiv_q_ui.o: $(srcdir)/fdiv_q_ui.c $(H)
+fdiv_qr.o: $(srcdir)/fdiv_qr.c $(H)
+fdiv_qr_ui.o: $(srcdir)/fdiv_qr_ui.c $(H)
+fdiv_r.o: $(srcdir)/fdiv_r.c $(H)
+fdiv_r_ui.o: $(srcdir)/fdiv_r_ui.c $(H)
+fdiv_ui.o: $(srcdir)/fdiv_ui.c $(H)
+gcd.o: $(srcdir)/gcd.c $(H) $(srcdir)/../longlong.h
+gcd_ui.o: $(srcdir)/gcd_ui.c $(H)
+gcdext.o: $(srcdir)/gcdext.c $(H)
+get_d.o: $(srcdir)/get_d.c $(H)
+get_si.o: $(srcdir)/get_si.c $(H)
+get_str.o: $(srcdir)/get_str.c $(H)
+get_ui.o: $(srcdir)/get_ui.c $(H)
+getlimbn.o: $(srcdir)/getlimbn.c $(H)
+hamdist.o: $(srcdir)/hamdist.c $(H)
+init.o: $(srcdir)/init.c $(H)
+inp_raw.o: $(srcdir)/inp_raw.c $(H)
+inp_str.o: $(srcdir)/inp_str.c $(H)
+invert.o: $(srcdir)/invert.c $(H)
+ior.o: $(srcdir)/ior.c $(H)
+iset.o: $(srcdir)/iset.c $(H)
+iset_d.o: $(srcdir)/iset_d.c $(H)
+iset_si.o: $(srcdir)/iset_si.c $(H)
+iset_str.o: $(srcdir)/iset_str.c $(H)
+iset_ui.o: $(srcdir)/iset_ui.c $(H)
+jacobi.o: $(srcdir)/jacobi.c $(H)
+legendre.o: $(srcdir)/legendre.c $(H)
+mod.o: $(srcdir)/mod.c $(H)
+tdiv_q_2exp.o: $(srcdir)/tdiv_q_2exp.c $(H)
+tdiv_r_2exp.o: $(srcdir)/tdiv_r_2exp.c $(H)
+mul.o: $(srcdir)/mul.c $(H)
+mul_2exp.o: $(srcdir)/mul_2exp.c $(H)
+mul_ui.o: $(srcdir)/mul_ui.c $(H)
+neg.o: $(srcdir)/neg.c $(H)
+out_raw.o: $(srcdir)/out_raw.c $(H)
+out_str.o: $(srcdir)/out_str.c $(H)
+perfsqr.o: $(srcdir)/perfsqr.c $(H)
+popcount.o: $(srcdir)/popcount.c $(H)
+pow_ui.o: $(srcdir)/pow_ui.c $(H) $(srcdir)/../longlong.h
+powm.o: $(srcdir)/powm.c $(H) $(srcdir)/../longlong.h
+powm_ui.o: $(srcdir)/powm_ui.c $(H) $(srcdir)/../longlong.h
+pprime_p.o: $(srcdir)/pprime_p.c $(H)
+random.o: $(srcdir)/random.c $(H) $(srcdir)/../urandom.h
+random2.o: $(srcdir)/random2.c $(H)
+realloc.o: $(srcdir)/realloc.c $(H)
+scan0.o: $(srcdir)/scan0.c $(H)
+scan1.o: $(srcdir)/scan1.c $(H)
+set.o: $(srcdir)/set.c $(H)
+set_d.o: $(srcdir)/set_d.c $(H)
+set_f.o: $(srcdir)/set_f.c $(H)
+set_q.o: $(srcdir)/set_q.c $(H)
+set_si.o: $(srcdir)/set_si.c $(H)
+set_str.o: $(srcdir)/set_str.c $(H) $(srcdir)/../longlong.h
+set_ui.o: $(srcdir)/set_ui.c $(H)
+setbit.o: $(srcdir)/setbit.c $(H)
+size.o: $(srcdir)/size.c $(H)
+sizeinbase.o: $(srcdir)/sizeinbase.c $(H) $(srcdir)/../longlong.h
+sqrt.o: $(srcdir)/sqrt.c $(H)
+sqrtrem.o: $(srcdir)/sqrtrem.c $(H)
+sub.o: $(srcdir)/sub.c $(H)
+sub_ui.o: $(srcdir)/sub_ui.c $(H)
+tdiv_q.o: $(srcdir)/tdiv_q.c $(H) $(srcdir)/../longlong.h
+tdiv_q_ui.o: $(srcdir)/tdiv_q_ui.c $(H)
+tdiv_qr.o: $(srcdir)/tdiv_qr.c $(H) $(srcdir)/../longlong.h $(srcdir)/dmincl.c $(H)
+tdiv_qr_ui.o: $(srcdir)/tdiv_qr_ui.c $(H)
+tdiv_r.o: $(srcdir)/tdiv_r.c $(H) $(srcdir)/../longlong.h $(srcdir)/dmincl.c $(H)
+tdiv_r_ui.o: $(srcdir)/tdiv_r_ui.c $(H)
+ui_pow_ui.o: $(srcdir)/ui_pow_ui.c $(H) $(srcdir)/../longlong.h
diff --git a/gnu/lib/libgmp/mpz/abs.c b/gnu/lib/libgmp/mpz/abs.c
new file mode 100644
index 0000000..080cac6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/abs.c
@@ -0,0 +1,51 @@
+/* mpz_abs(dst, src) -- Assign the absolute value of SRC to DST.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_abs (mpz_ptr w, mpz_srcptr u)
+#else
+mpz_abs (w, u)
+ mpz_ptr w;
+ mpz_srcptr u;
+#endif
+{
+ mp_ptr wp, up;
+ mp_size_t size;
+
+ size = ABS (u->_mp_size);
+
+ if (u != w)
+ {
+ if (w->_mp_alloc < size)
+ _mpz_realloc (w, size);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ MPN_COPY (wp, up, size);
+ }
+
+ w->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpz/add.c b/gnu/lib/libgmp/mpz/add.c
new file mode 100644
index 0000000..10dd970
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/add.c
@@ -0,0 +1,120 @@
+/* mpz_add -- Add two integers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_add (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_add (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+madd (mpz_srcptr u, mpz_srcptr v, mpz_ptr w)
+#else
+madd (u, v, w)
+ mpz_srcptr u;
+ mpz_srcptr v;
+ mpz_ptr w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_srcptr up, vp;
+ mp_ptr wp;
+ mp_size_t usize, vsize, wsize;
+ mp_size_t abs_usize;
+ mp_size_t abs_vsize;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+ abs_usize = ABS (usize);
+ abs_vsize = ABS (vsize);
+
+ if (abs_usize < abs_vsize)
+ {
+ /* Swap U and V. */
+ {const __mpz_struct *t = u; u = v; v = t;}
+ {mp_size_t t = usize; usize = vsize; vsize = t;}
+ {mp_size_t t = abs_usize; abs_usize = abs_vsize; abs_vsize = t;}
+ }
+
+ /* True: ABS_USIZE >= ABS_VSIZE. */
+
+ /* If not space for w (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ wp = w->_mp_d;
+
+ if ((usize ^ vsize) < 0)
+ {
+ /* U and V have different sign. Need to compare them to determine
+ which operand to subtract from which. */
+
+ /* This test is right since ABS_USIZE >= ABS_VSIZE. */
+ if (abs_usize != abs_vsize)
+ {
+ mpn_sub (wp, up, abs_usize, vp, abs_vsize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ else if (mpn_cmp (up, vp, abs_usize) < 0)
+ {
+ mpn_sub_n (wp, vp, up, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize >= 0)
+ wsize = -wsize;
+ }
+ else
+ {
+ mpn_sub_n (wp, up, vp, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ }
+ else
+ {
+ /* U and V have same sign. Add them. */
+ mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
+ wp[abs_usize] = cy_limb;
+ wsize = abs_usize + cy_limb;
+ if (usize < 0)
+ wsize = -wsize;
+ }
+
+ w->_mp_size = wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/add_ui.c b/gnu/lib/libgmp/mpz/add_ui.c
new file mode 100644
index 0000000..a1e4306
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/add_ui.c
@@ -0,0 +1,84 @@
+/* mpz_add_ui -- Add an mpz_t and an unsigned one-word integer.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_add_ui (mpz_ptr w, mpz_srcptr u, unsigned long int v)
+#else
+mpz_add_ui (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_srcptr up;
+ mp_ptr wp;
+ mp_size_t usize, wsize;
+ mp_size_t abs_usize;
+
+ usize = u->_mp_size;
+ abs_usize = ABS (usize);
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->_mp_d;
+ wp = w->_mp_d;
+
+ if (abs_usize == 0)
+ {
+ wp[0] = v;
+ w->_mp_size = v != 0;
+ return;
+ }
+
+ if (usize >= 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_add_1 (wp, up, abs_usize, v);
+ wp[abs_usize] = cy;
+ wsize = abs_usize + cy;
+ }
+ else
+ {
+ /* The signs are different. Need exact comparison to determine
+ which operand to subtract from which. */
+ if (abs_usize == 1 && up[0] < v)
+ {
+ wp[0] = v - up[0];
+ wsize = 1;
+ }
+ else
+ {
+ mpn_sub_1 (wp, up, abs_usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = -(abs_usize - (wp[abs_usize - 1] == 0));
+ }
+ }
+
+ w->_mp_size = wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/and.c b/gnu/lib/libgmp/mpz/and.c
new file mode 100644
index 0000000..838d4b1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/and.c
@@ -0,0 +1,278 @@
+/* mpz_and -- Logical and.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_and (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2)
+#else
+mpz_and (res, op1, op2)
+ mpz_ptr res;
+ mpz_srcptr op1;
+ mpz_srcptr op2;
+#endif
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size_t op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size_t res_size;
+ mp_size_t i;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ op1_size = op1->_mp_size;
+ op2_size = op2->_mp_size;
+
+ op1_ptr = op1->_mp_d;
+ op2_ptr = op2->_mp_d;
+ res_ptr = res->_mp_d;
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ res_size = MIN (op1_size, op2_size);
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ if (res->_mp_alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ op1_ptr = op1->_mp_d;
+ op2_ptr = op2->_mp_d;
+ res_ptr = res->_mp_d;
+ }
+
+ /* Second loop computes the real result. */
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & op2_ptr[i];
+
+ res->_mp_size = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ {
+ /* Fall through to the code at the end of the function. */
+ }
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx;
+ mp_limb_t cy;
+ mp_size_t res_alloc;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) & (-OP2)) = -(~(OP1 - 1) & ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) & ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) | (OP2 - 1)) + 1 */
+
+ /* It might seem as we could end up with an (invalid) result with
+ a leading zero-limb here when one of the operands is of the
+ type 1,,0,,..,,.0. But some analysis shows that we surely
+ would get carry into the zero-limb in this situation... */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ res_alloc = 1 + MAX (op1_size, op2_size);
+
+ opx = (mp_ptr) TMP_ALLOC (op1_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op1_ptr, op1_size, (mp_limb_t) 1);
+ op1_ptr = opx;
+
+ opx = (mp_ptr) TMP_ALLOC (op2_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ if (res->_mp_alloc < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ res_ptr = res->_mp_d;
+ /* Don't re-read OP1_PTR and OP2_PTR. They point to
+ temporary space--never to the space RES->_mp_D used
+ to point to before reallocation. */
+ }
+
+ if (op1_size >= op2_size)
+ {
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op1_size;
+ }
+ else
+ {
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ for (i = op1_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op2_size;
+ }
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+
+ res->_mp_size = -res_size;
+ TMP_FREE (marker);
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 & OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 & -OP2. */
+ {mpz_srcptr t = op1; op1 = op2; op2 = t;}
+ {mp_srcptr t = op1_ptr; op1_ptr = op2_ptr; op2_ptr = t;}
+ {mp_size_t t = op1_size; op1_size = op2_size; op2_size = t;}
+ }
+
+ }
+
+ {
+#if ANDNEW
+ mp_size_t op2_lim;
+ mp_size_t count;
+
+ /* OP2 must be negated as with infinite precision.
+
+ Scan from the low end for a non-zero limb. The first non-zero
+ limb is simply negated (two's complement). Any subsequent
+ limbs are one's complemented. Of course, we don't need to
+ handle more limbs than there are limbs in the other, positive
+ operand as the result for those limbs is going to become zero
+ anyway. */
+
+ /* Scan for the least significant. non-zero OP2 limb, and zero the
+ result meanwhile for those limb positions. (We will surely
+ find a non-zero limb, so we can write the loop with one
+ termination condition only.) */
+ for (i = 0; op2_ptr[i] == 0; i++)
+ res_ptr[i] = 0;
+ op2_lim = i;
+
+ op2_size = -op2_size;
+
+ if (op1_size <= op2_size)
+ {
+ /* The ones-extended OP2 is >= than the zero-extended OP1.
+ RES_SIZE <= OP1_SIZE. Find the exact size. */
+ for (i = op1_size - 1; i > op2_lim; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ for (i = res_size - 1; i > op2_lim; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+ res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim];
+ /* Yes, this *can* happen! */
+ MPN_NORMALIZE (res_ptr, res_size);
+ }
+ else
+ {
+ /* The ones-extended OP2 is < than the zero-extended OP1.
+ RES_SIZE == OP1_SIZE, since OP1 is normalized. */
+ res_size = op1_size;
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size, op1_size - op2_size);
+ for (i = op2_size - 1; i > op2_lim; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+ res_ptr[op2_lim] = op1_ptr[op2_lim] & -op2_ptr[op2_lim];
+ }
+
+ res->_mp_size = res_size;
+#else
+
+ /* OP1 is positive and zero-extended,
+ OP2 is negative and ones-extended.
+ The result will be positive.
+ OP1 & -OP2 = OP1 & ~(OP2 - 1). */
+
+ mp_ptr opx;
+
+ op2_size = -op2_size;
+ opx = (mp_ptr) TMP_ALLOC (op2_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ if (op1_size > op2_size)
+ {
+ /* The result has the same size as OP1, since OP1 is normalized
+ and longer than the ones-extended OP2. */
+ res_size = op1_size;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ if (res->_mp_alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->_mp_d;
+ op1_ptr = op1->_mp_d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->_mp_D used to point to before reallocation. */
+ }
+
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ res_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+
+ res->_mp_size = res_size;
+ }
+ else
+ {
+ /* Find out the exact result size. Ignore the high limbs of OP2,
+ OP1 is zero-extended and would make the result zero. */
+ for (i = op1_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now then we know exactly how much space is
+ needed for the result. */
+ if (res->_mp_alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->_mp_d;
+ op1_ptr = op1->_mp_d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->_mp_D used to point to before reallocation. */
+ }
+
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+
+ res->_mp_size = res_size;
+ }
+#endif
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/array_init.c b/gnu/lib/libgmp/mpz/array_init.c
new file mode 100644
index 0000000..8b2e85c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/array_init.c
@@ -0,0 +1,48 @@
+/* mpz_array_init (array, array_size, size_per_elem) --
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_array_init (mpz_ptr arr, mp_size_t arr_size, mp_size_t nbits)
+#else
+mpz_array_init (arr, arr_size, nbits)
+ mpz_ptr arr;
+ mp_size_t arr_size;
+ mp_size_t nbits;
+#endif
+{
+ register mp_ptr p;
+ register size_t i;
+ mp_size_t nlimbs;
+
+ nlimbs = (nbits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
+ p = (mp_ptr) (*_mp_allocate_func) (arr_size * nlimbs * BYTES_PER_MP_LIMB);
+
+ for (i = 0; i < arr_size; i++)
+ {
+ arr[i]._mp_alloc = nlimbs + 1; /* Yes, lie a little... */
+ arr[i]._mp_size = 0;
+ arr[i]._mp_d = p + i * nlimbs;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_q.c b/gnu/lib/libgmp/mpz/cdiv_q.c
new file mode 100644
index 0000000..860a232
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_q.c
@@ -0,0 +1,51 @@
+/* mpz_cdiv_q -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_cdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_cdiv_q (quot, dividend, divisor)
+ mpz_ptr quot;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t dividend_size = dividend->_mp_size;
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t rem;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ MPZ_TMP_INIT (rem, 1 + ABS (dividend_size));
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend_size) >= 0 && rem->_mp_size != 0)
+ mpz_add_ui (quot, quot, 1L);
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_q_ui.c b/gnu/lib/libgmp/mpz/cdiv_q_ui.c
new file mode 100644
index 0000000..7b6cfd7
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_q_ui.c
@@ -0,0 +1,64 @@
+/* mpz_cdiv_q_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_cdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_cdiv_q_ui (quot, dividend, divisor)
+ mpz_ptr quot;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size,
+ (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size >= 0)
+ {
+ mpn_add_1 (quot_ptr, quot_ptr, size, (mp_limb_t) 1);
+ remainder_limb = divisor - remainder_limb;
+ }
+
+ size -= size != 0 && quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_qr.c b/gnu/lib/libgmp/mpz/cdiv_qr.c
new file mode 100644
index 0000000..bf7d6da
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_qr.c
@@ -0,0 +1,62 @@
+/* mpz_cdiv_qr -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_cdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_cdiv_qr (quot, rem, dividend, divisor)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* We need the original value of the divisor after the quotient and
+ remainder have been preliminary calculated. We have to copy it to
+ temporary space if it's the same variable as either QUOT or REM. */
+ if (quot == divisor || rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend->_mp_size) >= 0 && rem->_mp_size != 0)
+ {
+ mpz_add_ui (quot, quot, 1L);
+ mpz_sub (rem, rem, divisor);
+ }
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_qr_ui.c b/gnu/lib/libgmp/mpz/cdiv_qr_ui.c
new file mode 100644
index 0000000..a780e77
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_qr_ui.c
@@ -0,0 +1,68 @@
+/* mpz_cdiv_qr_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_cdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_cdiv_qr_ui (quot, rem, dividend, divisor)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size,
+ (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size >= 0)
+ {
+ mpn_add_1 (quot_ptr, quot_ptr, size, (mp_limb_t) 1);
+ remainder_limb = divisor - remainder_limb;
+ }
+
+ size -= size != 0 && quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+
+ rem->_mp_d[0] = remainder_limb;
+ rem->_mp_size = -(remainder_limb != 0);
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_r.c b/gnu/lib/libgmp/mpz/cdiv_r.c
new file mode 100644
index 0000000..d34d138
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_r.c
@@ -0,0 +1,59 @@
+/* mpz_cdiv_r -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_cdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_cdiv_r (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend->_mp_size) >= 0 && rem->_mp_size != 0)
+ mpz_sub (rem, rem, divisor);
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_r_ui.c b/gnu/lib/libgmp/mpz/cdiv_r_ui.c
new file mode 100644
index 0000000..757a3f5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_r_ui.c
@@ -0,0 +1,54 @@
+/* mpz_cdiv_r_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_cdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_cdiv_r_ui (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size >= 0)
+ remainder_limb = divisor - remainder_limb;
+
+ rem->_mp_d[0] = remainder_limb;
+ rem->_mp_size = -(remainder_limb != 0);
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/cdiv_ui.c b/gnu/lib/libgmp/mpz/cdiv_ui.c
new file mode 100644
index 0000000..df841ed
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cdiv_ui.c
@@ -0,0 +1,50 @@
+/* mpz_cdiv_ui -- Division rounding the quotient towards +infinity. The
+ remainder gets the opposite sign as the denominator. In order to make it
+ always fit into the return type, the negative of the true remainder is
+ returned.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_cdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_cdiv_ui (dividend, divisor)
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size >= 0)
+ remainder_limb = divisor - remainder_limb;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/clear.c b/gnu/lib/libgmp/mpz/clear.c
new file mode 100644
index 0000000..00f3cfd
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/clear.c
@@ -0,0 +1,35 @@
+/* mpz_clear -- de-allocate the space occupied by the dynamic digit space of
+ an integer.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_clear (mpz_ptr m)
+#else
+mpz_clear (m)
+ mpz_ptr m;
+#endif
+{
+ (*_mp_free_func) (m->_mp_d, m->_mp_alloc * BYTES_PER_MP_LIMB);
+}
diff --git a/gnu/lib/libgmp/mpz/clrbit.c b/gnu/lib/libgmp/mpz/clrbit.c
new file mode 100644
index 0000000..59d9565
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/clrbit.c
@@ -0,0 +1,114 @@
+/* mpz_clrbit -- clear a specified bit.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_clrbit (mpz_ptr d, unsigned long int bit_index)
+#else
+mpz_clrbit (d, bit_index)
+ mpz_ptr d;
+ unsigned long int bit_index;
+#endif
+{
+ mp_size_t dsize = d->_mp_size;
+ mp_ptr dp = d->_mp_d;
+ mp_size_t limb_index;
+
+ limb_index = bit_index / BITS_PER_MP_LIMB;
+ if (dsize >= 0)
+ {
+ if (limb_index < dsize)
+ {
+ dp[limb_index] &= ~((mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB));
+ MPN_NORMALIZE (dp, dsize);
+ d->_mp_size = dsize;
+ }
+ else
+ ;
+ }
+ else
+ {
+ mp_size_t zero_bound;
+
+ /* Simulate two's complement arithmetic, i.e. simulate
+ 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
+ 2. clear the bit.
+ 3. Set OP = ~OP + 1. */
+
+ dsize = -dsize;
+
+ /* No upper bound on this loop, we're sure there's a non-zero limb
+ sooner ot later. */
+ for (zero_bound = 0; ; zero_bound++)
+ if (dp[zero_bound] != 0)
+ break;
+
+ if (limb_index > zero_bound)
+ {
+ if (limb_index < dsize)
+ dp[limb_index] |= (mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB);
+ else
+ {
+ /* Ugh. The bit should be cleared outside of the end of the
+ number. We have to increase the size of the number. */
+ if (d->_mp_alloc < limb_index + 1)
+ {
+ _mpz_realloc (d, limb_index + 1);
+ dp = d->_mp_d;
+ }
+ MPN_ZERO (dp + dsize, limb_index - dsize);
+ dp[limb_index] = (mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB);
+ d->_mp_size = -(limb_index + 1);
+ }
+ }
+ else if (limb_index == zero_bound)
+ {
+ dp[limb_index] = ((dp[limb_index] - 1)
+ | ((mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB))) + 1;
+ if (dp[limb_index] == 0)
+ {
+ mp_size_t i;
+ for (i = limb_index + 1; i < dsize; i++)
+ {
+ dp[i] += 1;
+ if (dp[i] != 0)
+ goto fin;
+ }
+ /* We got carry all way out beyond the end of D. Increase
+ its size (and allocation if necessary). */
+ dsize++;
+ if (d->_mp_alloc < dsize)
+ {
+ _mpz_realloc (d, dsize);
+ dp = d->_mp_d;
+ }
+ dp[i] = 1;
+ d->_mp_size = -dsize;
+ fin:;
+ }
+ }
+ else
+ ;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/cmp.c b/gnu/lib/libgmp/mpz/cmp.c
new file mode 100644
index 0000000..37be334
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cmp.c
@@ -0,0 +1,75 @@
+/* mpz_cmp(u,v) -- Compare U, V. Return postive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#ifdef BERKELEY_MP
+#include "mp.h"
+#endif
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+int
+#if __STDC__
+mpz_cmp (mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_cmp (u, v)
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#else /* BERKELEY_MP */
+int
+#if __STDC__
+mcmp (mpz_srcptr u, mpz_srcptr v)
+#else
+mcmp (u, v)
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize = v->_mp_size;
+ mp_size_t size;
+ mp_srcptr up, vp;
+ int cmp;
+
+ if (usize != vsize)
+ return usize - vsize;
+
+ if (usize == 0)
+ return 0;
+
+ size = ABS (usize);
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ cmp = mpn_cmp (up, vp, size);
+
+ if (cmp == 0)
+ return 0;
+
+ if ((cmp < 0) == (usize < 0))
+ return 1;
+ else
+ return -1;
+}
diff --git a/gnu/lib/libgmp/mpz/cmp_si.c b/gnu/lib/libgmp/mpz/cmp_si.c
new file mode 100644
index 0000000..8063fd3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cmp_si.c
@@ -0,0 +1,66 @@
+/* mpz_cmp_si(u,v) -- Compare an integer U with a single-word int V.
+ Return positive, zero, or negative based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* gmp.h defines a macro for mpz_cmp_si. */
+#undef mpz_cmp_si
+
+int
+#if __STDC__
+mpz_cmp_si (mpz_srcptr u, signed long int v_digit)
+#else
+mpz_cmp_si (u, v_digit)
+ mpz_srcptr u;
+ signed long int v_digit;
+#endif
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize;
+ mp_limb_t u_digit;
+
+ vsize = 0;
+ if (v_digit > 0)
+ vsize = 1;
+ else if (v_digit < 0)
+ {
+ vsize = -1;
+ v_digit = -v_digit;
+ }
+
+ if (usize != vsize)
+ return usize - vsize;
+
+ if (usize == 0)
+ return 0;
+
+ u_digit = u->_mp_d[0];
+
+ if (u_digit == v_digit)
+ return 0;
+
+ if (u_digit > v_digit)
+ return usize;
+ else
+ return -usize;
+}
diff --git a/gnu/lib/libgmp/mpz/cmp_ui.c b/gnu/lib/libgmp/mpz/cmp_ui.c
new file mode 100644
index 0000000..1a50b96
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/cmp_ui.c
@@ -0,0 +1,56 @@
+/* mpz_cmp_ui.c -- Compare a mpz_t a with an mp_limb_t b. Return positive,
+ zero, or negative based on if a > b, a == b, or a < b.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* gmp.h defines a macro for mpz_cmp_ui. */
+#undef mpz_cmp_ui
+
+int
+#if __STDC__
+mpz_cmp_ui (mpz_srcptr u, unsigned long int v_digit)
+#else
+mpz_cmp_ui (u, v_digit)
+ mpz_srcptr u;
+ unsigned long int v_digit;
+#endif
+{
+ mp_size_t usize = u->_mp_size;
+
+ if (usize == 0)
+ return -(v_digit != 0);
+
+ if (usize == 1)
+ {
+ mp_limb_t u_digit;
+
+ u_digit = u->_mp_d[0];
+ if (u_digit > v_digit)
+ return 1;
+ if (u_digit < v_digit)
+ return -1;
+ return 0;
+ }
+
+ return (usize > 0) ? 1 : -1;
+}
diff --git a/gnu/lib/libgmp/mpz/com.c b/gnu/lib/libgmp/mpz/com.c
new file mode 100644
index 0000000..559f2b6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/com.c
@@ -0,0 +1,93 @@
+/* mpz_com(mpz_ptr dst, mpz_ptr src) -- Assign the bit-complemented value of
+ SRC to DST.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_com (mpz_ptr dst, mpz_srcptr src)
+#else
+mpz_com (dst, src)
+ mpz_ptr dst;
+ mpz_srcptr src;
+#endif
+{
+ mp_size_t size = src->_mp_size;
+ mp_srcptr src_ptr;
+ mp_ptr dst_ptr;
+
+ if (size >= 0)
+ {
+ /* As with infinite precision: one's complement, two's complement.
+ But this can be simplified using the identity -x = ~x + 1.
+ So we're going to compute (~~x) + 1 = x + 1! */
+
+ if (dst->_mp_alloc < size + 1)
+ _mpz_realloc (dst, size + 1);
+
+ src_ptr = src->_mp_d;
+ dst_ptr = dst->_mp_d;
+
+ if (size == 0)
+ {
+ /* Special case, as mpn_add wants the first arg's size >= the
+ second arg's size. */
+ dst_ptr[0] = 1;
+ dst->_mp_size = -1;
+ return;
+ }
+
+ {
+ mp_limb_t cy;
+
+ cy = mpn_add_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1);
+ if (cy)
+ {
+ dst_ptr[size] = cy;
+ size++;
+ }
+ }
+
+ /* Store a negative size, to indicate ones-extension. */
+ dst->_mp_size = -size;
+ }
+ else
+ {
+ /* As with infinite precision: two's complement, then one's complement.
+ But that can be simplified using the identity -x = ~(x - 1).
+ So we're going to compute ~~(x - 1) = x - 1! */
+ size = -size;
+
+ if (dst->_mp_alloc < size)
+ _mpz_realloc (dst, size);
+
+ src_ptr = src->_mp_d;
+ dst_ptr = dst->_mp_d;
+
+ mpn_sub_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1);
+ size -= dst_ptr[size - 1] == 0;
+
+ /* Store a positive size, to indicate zero-extension. */
+ dst->_mp_size = size;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/configure.in b/gnu/lib/libgmp/mpz/configure.in
new file mode 100644
index 0000000..ed84461
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/configure.in
@@ -0,0 +1,12 @@
+# This file is a shell script fragment that supplies the information
+# necessary for a configure script to process the program in
+# this directory. For more information, look at ../configure.
+
+configdirs=tests
+srctrigger=add_ui.c
+srcname="GNU Multi-Precision library/mpz"
+
+# per-host:
+
+# per-target:
+
diff --git a/gnu/lib/libgmp/mpz/divexact.c b/gnu/lib/libgmp/mpz/divexact.c
new file mode 100644
index 0000000..b897448
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/divexact.c
@@ -0,0 +1,112 @@
+/* mpz_divexact -- finds quotient when known that quot * den == num && den != 0.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* Ken Weber (kweber@mat.ufrgs.br, kweber@mcs.kent.edu)
+
+ Funding for this work has been partially provided by Conselho Nacional
+ de Desenvolvimento Cienti'fico e Tecnolo'gico (CNPq) do Brazil, Grant
+ 301314194-2, and was done while I was a visiting reseacher in the Instituto
+ de Matema'tica at Universidade Federal do Rio Grande do Sul (UFRGS).
+
+ References:
+ T. Jebelean, An algorithm for exact division, Journal of Symbolic
+ Computation, v. 15, 1993, pp. 169-180. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
+#else
+mpz_divexact (quot, num, den)
+ mpz_ptr quot;
+ mpz_srcptr num;
+ mpz_srcptr den;
+#endif
+{
+ mp_ptr qp, tp;
+ mp_size_t qsize, tsize;
+
+ mp_srcptr np = num->_mp_d;
+ mp_srcptr dp = den->_mp_d;
+ mp_size_t nsize = ABS (num->_mp_size);
+ mp_size_t dsize = ABS (den->_mp_size);
+ TMP_DECL (marker);
+
+ /* Generate divide-by-zero error if dsize == 0. */
+ if (dsize == 0)
+ {
+ quot->_mp_size = 1 / dsize;
+ return;
+ }
+
+ if (nsize == 0)
+ {
+ quot->_mp_size = 0;
+ return;
+ }
+
+ qsize = nsize - dsize + 1;
+ if (quot->_mp_alloc < qsize)
+ _mpz_realloc (quot, qsize);
+ qp = quot->_mp_d;
+
+ TMP_MARK (marker);
+
+ /* QUOT <-- NUM/2^r, T <-- DEN/2^r where = r number of twos in DEN. */
+ while (dp[0] == 0)
+ np += 1, nsize -= 1, dp += 1, dsize -= 1;
+ tsize = MIN (qsize, dsize);
+ if (dp[0] & 1)
+ {
+ if (qp != dp)
+ MPN_COPY (qp, np, qsize);
+ if (qp == dp) /* QUOT and DEN overlap. */
+ {
+ tp = (mp_ptr) TMP_ALLOC (sizeof (mp_limb_t) * tsize);
+ MPN_COPY (tp, dp, tsize);
+ }
+ else
+ tp = (mp_ptr) dp;
+ }
+ else
+ {
+ unsigned long int r;
+ tp = (mp_ptr) TMP_ALLOC (sizeof (mp_limb_t) * tsize);
+ count_trailing_zeros (r, dp[0]);
+ mpn_rshift (tp, dp, tsize, r);
+ if (dsize > tsize)
+ tp[tsize-1] |= dp[tsize] << (BITS_PER_MP_LIMB - r);
+ mpn_rshift (qp, np, qsize, r);
+ if (nsize > qsize)
+ qp[qsize-1] |= np[qsize] << (BITS_PER_MP_LIMB - r);
+ }
+
+ /* Now QUOT <-- QUOT/T. */
+ mpn_bdivmod (qp, qp, qsize, tp, tsize, qsize * BITS_PER_MP_LIMB);
+ MPN_NORMALIZE (qp, qsize);
+
+ quot->_mp_size = (num->_mp_size < 0) == (den->_mp_size < 0) ? qsize : -qsize;
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/dmincl.c b/gnu/lib/libgmp/mpz/dmincl.c
new file mode 100644
index 0000000..51bd084
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/dmincl.c
@@ -0,0 +1,201 @@
+/* dmincl.c -- include file for tdiv_qr.c, tdiv_r.c.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+/* If den == quot, den needs temporary storage.
+ If den == rem, den needs temporary storage.
+ If num == quot, num needs temporary storage.
+ If den has temporary storage, it can be normalized while being copied,
+ i.e no extra storage should be allocated. */
+
+/* This is the function body of mdiv, mpz_divmod, and mpz_mod.
+
+ If COMPUTE_QUOTIENT is defined, the quotient is put in the MP_INT
+ object quot, otherwise that variable is not referenced at all.
+
+ The remainder is always computed, and the result is put in the MP_INT
+ object rem. */
+
+{
+ mp_ptr np, dp;
+ mp_ptr qp, rp;
+ mp_size_t nsize = num->_mp_size;
+ mp_size_t dsize = den->_mp_size;
+ mp_size_t qsize, rsize;
+ mp_size_t sign_remainder = nsize;
+#ifdef COMPUTE_QUOTIENT
+ mp_size_t sign_quotient = nsize ^ dsize;
+#endif
+ unsigned normalization_steps;
+ mp_limb_t q_limb;
+ TMP_DECL (marker);
+
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+
+ /* Ensure space is enough for quotient and remainder. */
+
+ /* We need space for an extra limb in the remainder, because it's
+ up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ if (rem->_mp_alloc < rsize)
+ _mpz_realloc (rem, rsize);
+
+ qsize = rsize - dsize; /* qsize cannot be bigger than this. */
+ if (qsize <= 0)
+ {
+ if (num != rem)
+ {
+ rem->_mp_size = num->_mp_size;
+ MPN_COPY (rem->_mp_d, num->_mp_d, nsize);
+ }
+#ifdef COMPUTE_QUOTIENT
+ /* This needs to follow the assignment to rem, in case the
+ numerator and quotient are the same. */
+ quot->_mp_size = 0;
+#endif
+ return;
+ }
+
+#ifdef COMPUTE_QUOTIENT
+ if (quot->_mp_alloc < qsize)
+ _mpz_realloc (quot, qsize);
+#endif
+
+ /* Read pointers here, when reallocation is finished. */
+ np = num->_mp_d;
+ dp = den->_mp_d;
+ rp = rem->_mp_d;
+
+ /* Optimize division by a single-limb divisor. */
+ if (dsize == 1)
+ {
+ mp_limb_t rlimb;
+#ifdef COMPUTE_QUOTIENT
+ qp = quot->_mp_d;
+ rlimb = mpn_divmod_1 (qp, np, nsize, dp[0]);
+ qsize -= qp[qsize - 1] == 0;
+ quot->_mp_size = sign_quotient >= 0 ? qsize : -qsize;
+#else
+ rlimb = mpn_mod_1 (np, nsize, dp[0]);
+#endif
+ rp[0] = rlimb;
+ rsize = rlimb != 0;
+ rem->_mp_size = sign_remainder >= 0 ? rsize : -rsize;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+#ifdef COMPUTE_QUOTIENT
+ qp = quot->_mp_d;
+
+ /* Make sure QP and NP point to different objects. Otherwise the
+ numerator would be gradually overwritten by the quotient limbs. */
+ if (qp == np)
+ {
+ /* Copy NP object to temporary space. */
+ np = (mp_ptr) TMP_ALLOC (nsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (np, qp, nsize);
+ }
+
+#else
+ /* Put quotient at top of remainder. */
+ qp = rp + dsize;
+#endif
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant word. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ significant word. Move the shifted numerator in the remainder
+ meanwhile. */
+ nlimb = mpn_lshift (rp, np, nsize, normalization_steps);
+ if (nlimb != 0)
+ {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else
+ {
+ /* The denominator is already normalized, as required. Copy it to
+ temporary space if it overlaps with the quotient or remainder. */
+#ifdef COMPUTE_QUOTIENT
+ if (dp == rp || dp == qp)
+#else
+ if (dp == rp)
+#endif
+ {
+ mp_ptr tp;
+
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (tp, dp, dsize);
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if (rp != np)
+ MPN_COPY (rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ q_limb = mpn_divmod (qp, rp, rsize, dp, dsize);
+
+#ifdef COMPUTE_QUOTIENT
+ qsize = rsize - dsize;
+ if (q_limb)
+ {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->_mp_size = sign_quotient >= 0 ? qsize : -qsize;
+#endif
+
+ rsize = dsize;
+ MPN_NORMALIZE (rp, rsize);
+
+ if (normalization_steps != 0 && rsize != 0)
+ {
+ mpn_rshift (rp, rp, rsize, normalization_steps);
+ rsize -= rp[rsize - 1] == 0;
+ }
+
+ rem->_mp_size = sign_remainder >= 0 ? rsize : -rsize;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/fac_ui.c b/gnu/lib/libgmp/mpz/fac_ui.c
new file mode 100644
index 0000000..a170060
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fac_ui.c
@@ -0,0 +1,157 @@
+/* mpz_fac_ui(result, n) -- Set RESULT to N!.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#ifdef DBG
+#include <stdio.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_fac_ui (mpz_ptr result, unsigned long int n)
+#else
+mpz_fac_ui (result, n)
+ mpz_ptr result;
+ unsigned long int n;
+#endif
+{
+#if SIMPLE_FAC
+
+ /* Be silly. Just multiply the numbers in ascending order. O(n**2). */
+
+ unsigned long int k;
+
+ mpz_set_ui (result, 1L);
+
+ for (k = 2; k <= n; k++)
+ mpz_mul_ui (result, result, k);
+#else
+
+ /* Be smarter. Multiply groups of numbers in ascending order until the
+ product doesn't fit in a limb. Multiply these partial product in a
+ balanced binary tree fashion, to make the operand have as equal sizes
+ as possible. When the operands have about the same size, mpn_mul
+ becomes faster. */
+
+ unsigned long int p, k;
+ mp_limb_t p1, p0;
+
+ /* Stack of partial products, used to make the computation balanced
+ (i.e. make the sizes of the multiplication operands equal). The
+ topmost position of MP_STACK will contain a one-limb partial product,
+ the second topmost will contain a two-limb partial product, and so
+ on. MP_STACK[0] will contain a partial product with 2**t limbs.
+ To compute n! MP_STACK needs to be less than
+ log(n)**2/log(BITS_PER_MP_LIMB), so 30 is surely enough. */
+#define MP_STACK_SIZE 30
+ mpz_t mp_stack[MP_STACK_SIZE];
+
+ /* TOP is an index into MP_STACK, giving the topmost element.
+ TOP_LIMIT_SO_FAR is the largets value it has taken so far. */
+ int top, top_limit_so_far;
+
+ /* Count of the total number of limbs put on MP_STACK so far. This
+ variable plays an essential role in making the compututation balanced.
+ See below. */
+ unsigned int tree_cnt;
+
+ top = top_limit_so_far = -1;
+ tree_cnt = 0;
+ p = 1;
+ for (k = 2; k <= n; k++)
+ {
+ /* Multiply the partial product in P with K. */
+ umul_ppmm (p1, p0, (mp_limb_t) p, (mp_limb_t) k);
+
+ /* Did we get overflow into the high limb, i.e. is the partial
+ product now more than one limb? */
+ if (p1 != 0)
+ {
+ tree_cnt++;
+
+ if (tree_cnt % 2 == 0)
+ {
+ mp_size_t i;
+
+ /* TREE_CNT is even (i.e. we have generated an even number of
+ one-limb partial products), which means that we have a
+ single-limb product on the top of MP_STACK. */
+
+ mpz_mul_ui (mp_stack[top], mp_stack[top], p);
+
+ /* If TREE_CNT is divisable by 4, 8,..., we have two
+ similar-sized partial products with 2, 4,... limbs at
+ the topmost two positions of MP_STACK. Multiply them
+ to form a new partial product with 4, 8,... limbs. */
+ for (i = 4; (tree_cnt & (i - 1)) == 0; i <<= 1)
+ {
+ mpz_mul (mp_stack[top - 1],
+ mp_stack[top], mp_stack[top - 1]);
+ top--;
+ }
+ }
+ else
+ {
+ /* Put the single-limb partial product in P on the stack.
+ (The next time we get a single-limb product, we will
+ multiply the two together.) */
+ top++;
+ if (top > top_limit_so_far)
+ {
+ if (top > MP_STACK_SIZE)
+ abort();
+ /* The stack is now bigger than ever, initialize the top
+ element. */
+ mpz_init_set_ui (mp_stack[top], p);
+ top_limit_so_far++;
+ }
+ else
+ mpz_set_ui (mp_stack[top], p);
+ }
+
+ /* We ignored the last result from umul_ppmm. Put K in P as the
+ first component of the next single-limb partial product. */
+ p = k;
+ }
+ else
+ /* We didn't get overflow in umul_ppmm. Put p0 in P and try
+ with one more value of K. */
+ p = p0; /* bogus if long != mp_limb_t */
+ }
+
+ /* We have partial products in mp_stack[0..top], in descending order.
+ We also have a small partial product in p.
+ Their product is the final result. */
+ if (top < 0)
+ mpz_set_ui (result, p);
+ else
+ mpz_mul_ui (result, mp_stack[top--], p);
+ while (top >= 0)
+ mpz_mul (result, result, mp_stack[top--]);
+
+ /* Free the storage allocated for MP_STACK. */
+ for (top = top_limit_so_far; top >= 0; top--)
+ mpz_clear (mp_stack[top]);
+#endif
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_q.c b/gnu/lib/libgmp/mpz/fdiv_q.c
new file mode 100644
index 0000000..3da943a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_q.c
@@ -0,0 +1,51 @@
+/* mpz_fdiv_q -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_fdiv_q (mpz_ptr quot, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_fdiv_q (quot, dividend, divisor)
+ mpz_ptr quot;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t dividend_size = dividend->_mp_size;
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t rem;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ MPZ_TMP_INIT (rem, 1 + ABS (dividend_size));
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend_size) < 0 && rem->_mp_size != 0)
+ mpz_sub_ui (quot, quot, 1L);
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_q_2exp.c b/gnu/lib/libgmp/mpz/fdiv_q_2exp.c
new file mode 100644
index 0000000..3f56baf
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_q_2exp.c
@@ -0,0 +1,94 @@
+/* mpz_fdiv_q_2exp -- Divide an integer by 2**CNT. Round the quotient
+ towards -infinity.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_fdiv_q_2exp (mpz_ptr w, mpz_srcptr u, unsigned long int cnt)
+#else
+mpz_fdiv_q_2exp (w, u, cnt)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int cnt;
+#endif
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t wsize;
+ mp_size_t abs_usize = ABS (usize);
+ mp_size_t limb_cnt;
+ mp_ptr wp;
+ mp_limb_t round = 0;
+
+ limb_cnt = cnt / BITS_PER_MP_LIMB;
+ wsize = abs_usize - limb_cnt;
+ if (wsize <= 0)
+ {
+ wp = w->_mp_d;
+ wsize = 0;
+ /* Set ROUND since we know we skip some non-zero words in this case.
+ Well, if U is zero, we don't, but then this will be taken care of
+ below, since rounding only really takes place for negative U. */
+ round = 1;
+ wp[0] = 1;
+ w->_mp_size = -(usize < 0);
+ return;
+ }
+ else
+ {
+ mp_size_t i;
+ mp_ptr up;
+
+ /* Make sure there is enough space. We make an extra limb
+ here to account for possible rounding at the end. */
+ if (w->_mp_alloc < wsize + 1)
+ _mpz_realloc (w, wsize + 1);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ /* Set ROUND if we are about skip some non-zero limbs. */
+ for (i = 0; i < limb_cnt && round == 0; i++)
+ round = up[i];
+
+ cnt %= BITS_PER_MP_LIMB;
+ if (cnt != 0)
+ {
+ round |= mpn_rshift (wp, up + limb_cnt, wsize, cnt);
+ wsize -= wp[wsize - 1] == 0;
+ }
+ else
+ {
+ MPN_COPY_INCR (wp, up + limb_cnt, wsize);
+ }
+ }
+
+ if (usize < 0 && round != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_add_1 (wp, wp, wsize, 1);
+ wp[wsize] = cy;
+ wsize += cy;
+ }
+ w->_mp_size = usize >= 0 ? wsize : -wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_q_ui.c b/gnu/lib/libgmp/mpz/fdiv_q_ui.c
new file mode 100644
index 0000000..3d6825d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_q_ui.c
@@ -0,0 +1,62 @@
+/* mpz_fdiv_q_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_fdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_fdiv_q_ui (quot, dividend, divisor)
+ mpz_ptr quot;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size,
+ (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size < 0)
+ {
+ mpn_add_1 (quot_ptr, quot_ptr, size, (mp_limb_t) 1);
+ remainder_limb = divisor - remainder_limb;
+ }
+
+ size -= size != 0 && quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_qr.c b/gnu/lib/libgmp/mpz/fdiv_qr.c
new file mode 100644
index 0000000..2abb16c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_qr.c
@@ -0,0 +1,62 @@
+/* mpz_fdiv_qr -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_fdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_fdiv_qr (quot, rem, dividend, divisor)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* We need the original value of the divisor after the quotient and
+ remainder have been preliminary calculated. We have to copy it to
+ temporary space if it's the same variable as either QUOT or REM. */
+ if (quot == divisor || rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_qr (quot, rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend->_mp_size) < 0 && rem->_mp_size != 0)
+ {
+ mpz_sub_ui (quot, quot, 1L);
+ mpz_add (rem, rem, divisor);
+ }
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_qr_ui.c b/gnu/lib/libgmp/mpz/fdiv_qr_ui.c
new file mode 100644
index 0000000..a22b702
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_qr_ui.c
@@ -0,0 +1,66 @@
+/* mpz_fdiv_qr_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_fdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_fdiv_qr_ui (quot, rem, dividend, divisor)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size,
+ (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size < 0)
+ {
+ mpn_add_1 (quot_ptr, quot_ptr, size, (mp_limb_t) 1);
+ remainder_limb = divisor - remainder_limb;
+ }
+
+ size -= size != 0 && quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+
+ rem->_mp_d[0] = remainder_limb;
+ rem->_mp_size = remainder_limb != 0;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_r.c b/gnu/lib/libgmp/mpz/fdiv_r.c
new file mode 100644
index 0000000..14e045b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_r.c
@@ -0,0 +1,58 @@
+/* mpz_fdiv_r -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_fdiv_r (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_fdiv_r (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ if ((divisor_size ^ dividend->_mp_size) < 0 && rem->_mp_size != 0)
+ mpz_add (rem, rem, divisor);
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_r_2exp.c b/gnu/lib/libgmp/mpz/fdiv_r_2exp.c
new file mode 100644
index 0000000..04190b1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_r_2exp.c
@@ -0,0 +1,88 @@
+/* mpz_fdiv_r_2exp -- Divide a integer by 2**CNT and produce a remainder.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_fdiv_r_2exp (mpz_ptr res, mpz_srcptr in, unsigned long int cnt)
+#else
+mpz_fdiv_r_2exp (res, in, cnt)
+ mpz_ptr res;
+ mpz_srcptr in;
+ unsigned long int cnt;
+#endif
+{
+ mp_size_t in_size = ABS (in->_mp_size);
+ mp_size_t res_size;
+ mp_size_t limb_cnt = cnt / BITS_PER_MP_LIMB;
+ mp_srcptr in_ptr = in->_mp_d;
+
+ if (in_size > limb_cnt)
+ {
+ /* The input operand is (probably) greater than 2**CNT. */
+ mp_limb_t x;
+
+ x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % BITS_PER_MP_LIMB) - 1);
+ if (x != 0)
+ {
+ res_size = limb_cnt + 1;
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ res->_mp_d[limb_cnt] = x;
+ }
+ else
+ {
+ res_size = limb_cnt;
+ MPN_NORMALIZE (in_ptr, res_size);
+
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+ }
+ else
+ {
+ /* The input operand is smaller than 2**CNT. We perform a no-op,
+ apart from that we might need to copy IN to RES. */
+ res_size = in_size;
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+
+ if (res != in)
+ MPN_COPY (res->_mp_d, in->_mp_d, limb_cnt);
+ res->_mp_size = res_size;
+ if (in->_mp_size < 0 && res_size != 0)
+ {
+ /* Result should be 2^CNT - RES */
+ mpz_t tmp;
+ MPZ_TMP_INIT (tmp, limb_cnt + 1);
+ mpz_set_ui (tmp, 1L);
+ mpz_mul_2exp (tmp, tmp, cnt);
+ mpz_sub (res, tmp, res);
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_r_ui.c b/gnu/lib/libgmp/mpz/fdiv_r_ui.c
new file mode 100644
index 0000000..c4c3749
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_r_ui.c
@@ -0,0 +1,52 @@
+/* mpz_fdiv_r_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_fdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_fdiv_r_ui (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size < 0)
+ remainder_limb = divisor - remainder_limb;
+
+ rem->_mp_d[0] = remainder_limb;
+ rem->_mp_size = remainder_limb != 0;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/fdiv_ui.c b/gnu/lib/libgmp/mpz/fdiv_ui.c
new file mode 100644
index 0000000..4d018a2
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/fdiv_ui.c
@@ -0,0 +1,48 @@
+/* mpz_fdiv_ui -- Division rounding the quotient towards -infinity.
+ The remainder gets the same sign as the denominator.
+
+Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_fdiv_ui (mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_fdiv_ui (dividend, divisor)
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ if (remainder_limb != 0 && dividend_size < 0)
+ remainder_limb = divisor - remainder_limb;
+
+ return remainder_limb;
+}
diff --git a/gnu/lib/libgmp/mpz/gcd.c b/gnu/lib/libgmp/mpz/gcd.c
new file mode 100644
index 0000000..f93030c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/gcd.c
@@ -0,0 +1,178 @@
+/* mpz/gcd.c: Calculate the greatest common divisor of two integers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void *_mpz_realloc ();
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_gcd (mpz_ptr g, mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_gcd (g, u, v)
+ mpz_ptr g;
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+gcd (mpz_srcptr u, mpz_srcptr v, mpz_ptr g)
+#else
+gcd (u, v, g)
+ mpz_ptr g;
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#endif /* BERKELEY_MP */
+
+{
+ unsigned long int g_zero_bits, u_zero_bits, v_zero_bits;
+ mp_size_t g_zero_limbs, u_zero_limbs, v_zero_limbs;
+ mp_ptr tp;
+ mp_ptr up = u->_mp_d;
+ mp_size_t usize = ABS (u->_mp_size);
+ mp_ptr vp = v->_mp_d;
+ mp_size_t vsize = ABS (v->_mp_size);
+ mp_size_t gsize;
+ TMP_DECL (marker);
+
+ /* GCD(0, V) == V. */
+ if (usize == 0)
+ {
+ g->_mp_size = vsize;
+ if (g == v)
+ return;
+ if (g->_mp_alloc < vsize)
+ _mpz_realloc (g, vsize);
+ MPN_COPY (g->_mp_d, vp, vsize);
+ return;
+ }
+
+ /* GCD(U, 0) == U. */
+ if (vsize == 0)
+ {
+ g->_mp_size = usize;
+ if (g == u)
+ return;
+ if (g->_mp_alloc < usize)
+ _mpz_realloc (g, usize);
+ MPN_COPY (g->_mp_d, up, usize);
+ return;
+ }
+
+ if (usize == 1)
+ {
+ g->_mp_size = 1;
+ g->_mp_d[0] = mpn_gcd_1 (vp, vsize, up[0]);
+ return;
+ }
+
+ if (vsize == 1)
+ {
+ g->_mp_size = 1;
+ g->_mp_d[0] = mpn_gcd_1 (up, usize, vp[0]);
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Eliminate low zero bits from U and V and move to temporary storage. */
+ while (*up == 0)
+ up++;
+ u_zero_limbs = up - u->_mp_d;
+ usize -= u_zero_limbs;
+ count_trailing_zeros (u_zero_bits, *up);
+ tp = up;
+ up = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ if (u_zero_bits != 0)
+ {
+ mpn_rshift (up, tp, usize, u_zero_bits);
+ usize -= up[usize - 1] == 0;
+ }
+ else
+ MPN_COPY (up, tp, usize);
+
+ while (*vp == 0)
+ vp++;
+ v_zero_limbs = vp - v->_mp_d;
+ vsize -= v_zero_limbs;
+ count_trailing_zeros (v_zero_bits, *vp);
+ tp = vp;
+ vp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ if (v_zero_bits != 0)
+ {
+ mpn_rshift (vp, tp, vsize, v_zero_bits);
+ vsize -= vp[vsize - 1] == 0;
+ }
+ else
+ MPN_COPY (vp, tp, vsize);
+
+ if (u_zero_limbs > v_zero_limbs)
+ {
+ g_zero_limbs = v_zero_limbs;
+ g_zero_bits = v_zero_bits;
+ }
+ else if (u_zero_limbs < v_zero_limbs)
+ {
+ g_zero_limbs = u_zero_limbs;
+ g_zero_bits = u_zero_bits;
+ }
+ else /* Equal. */
+ {
+ g_zero_limbs = u_zero_limbs;
+ g_zero_bits = MIN (u_zero_bits, v_zero_bits);
+ }
+
+ /* Call mpn_gcd. The 1st argument must not have more bits than the 2nd. */
+ vsize = (usize < vsize || (usize == vsize && up[usize-1] < vp[vsize-1]))
+ ? mpn_gcd (vp, up, usize, vp, vsize)
+ : mpn_gcd (vp, vp, vsize, up, usize);
+
+ /* Here G <-- V << (g_zero_limbs*BITS_PER_MP_LIMB + g_zero_bits). */
+ gsize = vsize + g_zero_limbs;
+ if (g_zero_bits != 0)
+ {
+ mp_limb_t cy_limb;
+ gsize += (vp[vsize - 1] >> (BITS_PER_MP_LIMB - g_zero_bits)) != 0;
+ if (g->_mp_alloc < gsize)
+ _mpz_realloc (g, gsize);
+ MPN_ZERO (g->_mp_d, g_zero_limbs);
+
+ tp = g->_mp_d + g_zero_limbs;
+ cy_limb = mpn_lshift (tp, vp, vsize, g_zero_bits);
+ if (cy_limb != 0)
+ tp[vsize] = cy_limb;
+ }
+ else
+ {
+ if (g->_mp_alloc < gsize)
+ _mpz_realloc (g, gsize);
+ MPN_ZERO (g->_mp_d, g_zero_limbs);
+ MPN_COPY (g->_mp_d + g_zero_limbs, vp, vsize);
+ }
+
+ g->_mp_size = gsize;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/gcd_ui.c b/gnu/lib/libgmp/mpz/gcd_ui.c
new file mode 100644
index 0000000..388ab05
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/gcd_ui.c
@@ -0,0 +1,64 @@
+/* mpz_gcd_ui -- Calculate the greatest common divisior of two integers.
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_gcd_ui (mpz_ptr w, mpz_srcptr u, unsigned long int v)
+#else
+mpz_gcd_ui (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_size_t size;
+ mp_limb_t res;
+
+ size = ABS (u->_mp_size);
+
+ if (size == 0)
+ res = v;
+ else if (v == 0)
+ {
+ if (w != NULL && u != w)
+ {
+ if (w->_mp_alloc < size)
+ _mpz_realloc (w, size);
+
+ MPN_COPY (w->_mp_d, u->_mp_d, size);
+ }
+ w->_mp_size = size;
+ /* We can't return any useful result for gcd(big,0). */
+ return size > 1 ? 0 : w->_mp_d[0];
+ }
+ else
+ res = mpn_gcd_1 (u->_mp_d, size, v);
+
+ if (w != NULL)
+ {
+ w->_mp_d[0] = res;
+ w->_mp_size = 1;
+ }
+ return res;
+}
diff --git a/gnu/lib/libgmp/mpz/gcdext.c b/gnu/lib/libgmp/mpz/gcdext.c
new file mode 100644
index 0000000..adf66b0
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/gcdext.c
@@ -0,0 +1,88 @@
+/* mpz_gcdext(g, s, t, a, b) -- Set G to gcd(a, b), and S and T such that
+ g = as + bt.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Botch: SLOW! */
+
+void
+#if __STDC__
+mpz_gcdext (mpz_ptr g, mpz_ptr s, mpz_ptr t, mpz_srcptr a, mpz_srcptr b)
+#else
+mpz_gcdext (g, s, t, a, b)
+ mpz_ptr g;
+ mpz_ptr s;
+ mpz_ptr t;
+ mpz_srcptr a;
+ mpz_srcptr b;
+#endif
+{
+ mpz_t s0, s1, q, r, x, d0, d1;
+
+ mpz_init_set_ui (s0, 1L);
+ mpz_init_set_ui (s1, 0L);
+ mpz_init (q);
+ mpz_init (r);
+ mpz_init (x);
+ mpz_init_set (d0, a);
+ mpz_init_set (d1, b);
+
+ while (d1->_mp_size != 0)
+ {
+ mpz_tdiv_qr (q, r, d0, d1);
+ mpz_set (d0, d1);
+ mpz_set (d1, r);
+
+ mpz_mul (x, s1, q);
+ mpz_sub (x, s0, x);
+ mpz_set (s0, s1);
+ mpz_set (s1, x);
+ }
+
+ if (t != NULL)
+ {
+ mpz_mul (x, s0, a);
+ mpz_sub (x, d0, x);
+ if (b->_mp_size == 0)
+ t->_mp_size = 0;
+ else
+ mpz_tdiv_q (t, x, b);
+ }
+ mpz_set (s, s0);
+ mpz_set (g, d0);
+ if (g->_mp_size < 0)
+ {
+ g->_mp_size = -g->_mp_size;
+ s->_mp_size = -s->_mp_size;
+ if (t != NULL)
+ t->_mp_size = -t->_mp_size;
+ }
+
+ mpz_clear (s0);
+ mpz_clear (s1);
+ mpz_clear (q);
+ mpz_clear (r);
+ mpz_clear (x);
+ mpz_clear (d0);
+ mpz_clear (d1);
+}
diff --git a/gnu/lib/libgmp/mpz/get_d.c b/gnu/lib/libgmp/mpz/get_d.c
new file mode 100644
index 0000000..0fd7916
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/get_d.c
@@ -0,0 +1,54 @@
+/* double mpz_get_d (mpz_t src) -- Return the double approximation to SRC.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+double
+#if __STDC__
+mpz_get_d (mpz_srcptr src)
+#else
+mpz_get_d (src)
+ mpz_srcptr src;
+#endif
+{
+ double res;
+ mp_size_t size, i, n_limbs_to_use;
+ int negative;
+ mp_ptr qp;
+
+ size = SIZ(src);
+ if (size == 0)
+ return 0.0;
+
+ negative = size < 0;
+ size = ABS (size);
+ qp = PTR(src);
+
+ res = qp[size - 1];
+ n_limbs_to_use = MIN (LIMBS_PER_DOUBLE, size);
+ for (i = 2; i <= n_limbs_to_use; i++)
+ res = res * MP_BASE_AS_DOUBLE + qp[size - i];
+
+ res = __gmp_scale2 (res, (size - n_limbs_to_use) * BITS_PER_MP_LIMB);
+
+ return negative ? -res : res;
+}
diff --git a/gnu/lib/libgmp/mpz/get_si.c b/gnu/lib/libgmp/mpz/get_si.c
new file mode 100644
index 0000000..45e0e5a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/get_si.c
@@ -0,0 +1,43 @@
+/* mpz_get_si(integer) -- Return the least significant digit from INTEGER.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+signed long int
+#if __STDC__
+mpz_get_si (mpz_srcptr op)
+#else
+mpz_get_si (op)
+ mpz_srcptr op;
+#endif
+{
+ mp_size_t size = op->_mp_size;
+ mp_limb_t low_limb = op->_mp_d[0];
+
+ if (size > 0)
+ return low_limb % ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1));
+ else if (size < 0)
+ /* This convoluted expression is necessary to properly handle 0x80000000 */
+ return ~((low_limb - 1) % ((mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1)));
+ else
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpz/get_str.c b/gnu/lib/libgmp/mpz/get_str.c
new file mode 100644
index 0000000..8ccf3ef
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/get_str.c
@@ -0,0 +1,118 @@
+/* mpz_get_str (string, base, mp_src) -- Convert the multiple precision
+ number MP_SRC to a string STRING of base BASE. If STRING is NULL
+ allocate space for the result. In any case, return a pointer to the
+ result. If STRING is not NULL, the caller must ensure enough space is
+ available to store the result.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+char *
+#if __STDC__
+mpz_get_str (char *res_str, int base, mpz_srcptr x)
+#else
+mpz_get_str (res_str, base, x)
+ char *res_str;
+ int base;
+ mpz_srcptr x;
+#endif
+{
+ mp_ptr xp;
+ mp_size_t x_size = x->_mp_size;
+ unsigned char *str;
+ char *return_str;
+ size_t str_size;
+ char *num_to_text;
+ int i;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ if (base >= 0)
+ {
+ if (base == 0)
+ base = 10;
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ }
+ else
+ {
+ base = -base;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ /* We allways allocate space for the string. If the caller passed a
+ NULL pointer for RES_STR, we allocate permanent space and return
+ a pointer to that to the caller. */
+ str_size = ((size_t) (ABS (x_size) * BITS_PER_MP_LIMB
+ * __mp_bases[base].chars_per_bit_exactly)) + 3;
+ if (res_str == 0)
+ {
+ /* We didn't get a string from the user. Allocate one (and return
+ a pointer to it). */
+ res_str = (char *) (*_mp_allocate_func) (str_size);
+ /* Make str, the variable used for raw result from mpn_get_str,
+ point to the same string, but just after a possible minus sign. */
+ str = (unsigned char *) res_str + 1;
+ }
+ else
+ {
+ /* Use TMP_ALLOC to get temporary space, since we need a few extra bytes
+ that we can't expect to caller to supply us with. */
+ str = (unsigned char *) TMP_ALLOC (str_size);
+ }
+
+ return_str = res_str;
+
+ if (x_size == 0)
+ {
+ res_str[0] = '0';
+ res_str[1] = 0;
+ TMP_FREE (marker);
+ return res_str;
+ }
+ if (x_size < 0)
+ {
+ *res_str++ = '-';
+ x_size = -x_size;
+ }
+
+ /* Move the number to convert into temporary space, since mpn_get_str
+ clobbers its argument + needs one extra high limb.... */
+ xp = (mp_ptr) TMP_ALLOC ((x_size + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (xp, x->_mp_d, x_size);
+
+ str_size = mpn_get_str (str, base, xp, x_size);
+
+ /* mpn_get_str might make some leading zeros. Skip them. */
+ while (*str == 0)
+ {
+ str_size--;
+ str++;
+ }
+
+ /* Translate result to printable chars and move result to RES_STR. */
+ for (i = 0; i < str_size; i++)
+ res_str[i] = num_to_text[str[i]];
+ res_str[str_size] = 0;
+
+ TMP_FREE (marker);
+ return return_str;
+}
diff --git a/gnu/lib/libgmp/mpz/get_ui.c b/gnu/lib/libgmp/mpz/get_ui.c
new file mode 100644
index 0000000..4bfb5e1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/get_ui.c
@@ -0,0 +1,37 @@
+/* mpz_get_ui(integer) -- Return the least significant digit from INTEGER.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_get_ui (mpz_srcptr integer)
+#else
+mpz_get_ui (integer)
+ mpz_srcptr integer;
+#endif
+{
+ if (integer->_mp_size == 0)
+ return 0;
+ else
+ return integer->_mp_d[0];
+}
diff --git a/gnu/lib/libgmp/mpz/getlimbn.c b/gnu/lib/libgmp/mpz/getlimbn.c
new file mode 100644
index 0000000..c7a234b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/getlimbn.c
@@ -0,0 +1,38 @@
+/* mpz_getlimbn(integer,n) -- Return the N:th limb from INTEGER.
+
+Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+mp_limb_t
+#if __STDC__
+mpz_getlimbn (mpz_srcptr integer, mp_size_t n)
+#else
+mpz_getlimbn (integer, n)
+ mpz_srcptr integer;
+ mp_size_t n;
+#endif
+{
+ if (integer->_mp_size <= n || n < 0)
+ return 0;
+ else
+ return integer->_mp_d[n];
+}
diff --git a/gnu/lib/libgmp/mpz/hamdist.c b/gnu/lib/libgmp/mpz/hamdist.c
new file mode 100644
index 0000000..58c9273
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/hamdist.c
@@ -0,0 +1,62 @@
+/* mpz_hamdist(mpz_ptr op1, mpz_ptr op2) -- Compute the hamming distance
+ between OP1 and OP2. If one of the operands is negative, return ~0. (We
+ could make the function well-defined when both operands are negative, but
+ that would probably not be worth the trouble.
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_hamdist (mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_hamdist (u, v)
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+{
+ mp_srcptr up, vp;
+ mp_size_t usize, vsize, size;
+ unsigned long int count;
+
+ usize = u->_mp_size;
+ vsize = v->_mp_size;
+
+ if ((usize | vsize) < 0)
+ return ~ (unsigned long int) 0;
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+
+ if (usize > vsize)
+ {
+ count = mpn_popcount (up + vsize, usize - vsize);
+ size = vsize;
+ }
+ else
+ {
+ count = mpn_popcount (vp + usize, vsize - usize);
+ size = usize;
+ }
+
+ return count + mpn_hamdist (up, vp, size);
+}
diff --git a/gnu/lib/libgmp/mpz/init.c b/gnu/lib/libgmp/mpz/init.c
new file mode 100644
index 0000000..f8d8e20
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/init.c
@@ -0,0 +1,36 @@
+/* mpz_init() -- Make a new multiple precision number with value 0.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_init (mpz_ptr x)
+#else
+mpz_init (x)
+ mpz_ptr x;
+#endif
+{
+ x->_mp_alloc = 1;
+ x->_mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz/inp_raw.c b/gnu/lib/libgmp/mpz/inp_raw.c
new file mode 100644
index 0000000..e1cec1d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/inp_raw.c
@@ -0,0 +1,101 @@
+/* mpz_inp_raw -- Input a mpz_t in raw, but endianess, and wordsize
+ independent format (as output by mpz_out_raw).
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpz_inp_raw (mpz_ptr x, FILE *stream)
+#else
+mpz_inp_raw (x, stream)
+ mpz_ptr x;
+ FILE *stream;
+#endif
+{
+ int i;
+ mp_size_t s;
+ mp_size_t xsize;
+ mp_ptr xp;
+ unsigned int c;
+ mp_limb_t x_limb;
+ mp_size_t in_bytesize;
+ int neg_flag;
+
+ if (stream == 0)
+ stream = stdin;
+
+ /* Read 4-byte size */
+ in_bytesize = 0;
+ for (i = 4 - 1; i >= 0; i--)
+ {
+ c = fgetc (stream);
+ in_bytesize = (in_bytesize << BITS_PER_CHAR) | c;
+ }
+
+ /* Size is stored as a 32 bit word; sign extend in_bytesize for non-32 bit
+ machines. */
+ if (sizeof (mp_size_t) > 4)
+ in_bytesize |= (-(in_bytesize < 0)) << 31;
+
+ neg_flag = in_bytesize < 0;
+ in_bytesize = ABS (in_bytesize);
+ xsize = (in_bytesize + BYTES_PER_MP_LIMB - 1) / BYTES_PER_MP_LIMB;
+
+ if (xsize == 0)
+ {
+ x->_mp_size = 0;
+ return 4; /* we've read 4 bytes */
+ }
+
+ if (x->_mp_alloc < xsize)
+ _mpz_realloc (x, xsize);
+ xp = x->_mp_d;
+
+ x_limb = 0;
+ for (i = (in_bytesize - 1) % BYTES_PER_MP_LIMB; i >= 0; i--)
+ {
+ c = fgetc (stream);
+ x_limb = (x_limb << BITS_PER_CHAR) | c;
+ }
+ xp[xsize - 1] = x_limb;
+
+ for (s = xsize - 2; s >= 0; s--)
+ {
+ x_limb = 0;
+ for (i = BYTES_PER_MP_LIMB - 1; i >= 0; i--)
+ {
+ c = fgetc (stream);
+ x_limb = (x_limb << BITS_PER_CHAR) | c;
+ }
+ xp[s] = x_limb;
+ }
+
+ if (c == EOF)
+ return 0; /* error */
+
+ MPN_NORMALIZE (xp, xsize);
+ x->_mp_size = neg_flag ? -xsize : xsize;
+ return in_bytesize + 4;
+}
diff --git a/gnu/lib/libgmp/mpz/inp_str.c b/gnu/lib/libgmp/mpz/inp_str.c
new file mode 100644
index 0000000..7159062
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/inp_str.c
@@ -0,0 +1,138 @@
+/* mpz_inp_str(dest_integer, stream, base) -- Input a number in base
+ BASE from stdio stream STREAM and store the result in DEST_INTEGER.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static int
+digit_value_in_base (c, base)
+ int c;
+ int base;
+{
+ int digit;
+
+ if (isdigit (c))
+ digit = c - '0';
+ else if (islower (c))
+ digit = c - 'a' + 10;
+ else if (isupper (c))
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ if (digit < base)
+ return digit;
+ return -1;
+}
+
+size_t
+#if __STDC__
+mpz_inp_str (mpz_ptr dest, FILE *stream, int base)
+#else
+mpz_inp_str (dest, stream, base)
+ mpz_ptr dest;
+ FILE *stream;
+ int base;
+#endif
+{
+ char *str;
+ size_t alloc_size, str_size;
+ int c;
+ int negative;
+ mp_size_t dest_size;
+ size_t nread;
+
+ if (stream == 0)
+ stream = stdin;
+
+ alloc_size = 100;
+ str = (char *) (*_mp_allocate_func) (alloc_size);
+ str_size = 0;
+ nread = 0;
+
+ /* Skip whitespace. */
+ do
+ {
+ c = getc (stream);
+ nread++;
+ }
+ while (isspace (c));
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = getc (stream);
+ }
+
+ if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
+ return 0; /* error if no digits */
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+ if (c == '0')
+ {
+ base = 8;
+ c = getc (stream);
+ nread++;
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ c = getc (stream);
+ nread++;
+ }
+ }
+ }
+
+ for (;;)
+ {
+ int dig;
+ if (str_size >= alloc_size)
+ {
+ size_t old_alloc_size = alloc_size;
+ alloc_size = alloc_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_alloc_size, alloc_size);
+ }
+ dig = digit_value_in_base (c, base);
+ if (dig < 0)
+ break;
+ str[str_size++] = dig;
+ c = getc (stream);
+ }
+
+ ungetc (c, stream);
+
+ dest_size = str_size / __mp_bases[base].chars_per_limb + 1;
+ if (dest->_mp_alloc < dest_size)
+ _mpz_realloc (dest, dest_size);
+
+ dest_size = mpn_set_str (dest->_mp_d, (unsigned char *) str, str_size, base);
+ dest->_mp_size = negative ? -dest_size : dest_size;
+
+ (*_mp_free_func) (str, alloc_size);
+ return str_size + nread;
+}
diff --git a/gnu/lib/libgmp/mpz/invert.c b/gnu/lib/libgmp/mpz/invert.c
new file mode 100644
index 0000000..ff1d6d9
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/invert.c
@@ -0,0 +1,43 @@
+/* mpz_invert (inv, x, n). Find multiplicative inverse of X in Z(N).
+ If X has an inverse, return non-zero and store inverse in INVERSE,
+ otherwise, return 0 and put garbage in X.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+
+int
+#if __STDC__
+mpz_invert (mpz_ptr inverse, mpz_srcptr x, mpz_srcptr n)
+#else
+mpz_invert (inverse, x, n)
+ mpz_ptr inverse;
+ mpz_srcptr x, n;
+#endif
+{
+ mpz_t gcd;
+ int rv;
+
+ mpz_init (gcd);
+ mpz_gcdext (gcd, inverse, (mpz_ptr) 0, x, n);
+ rv = gcd->_mp_size == 1 && (gcd->_mp_d)[0] == 1;
+ mpz_clear (gcd);
+ return rv;
+}
diff --git a/gnu/lib/libgmp/mpz/ior.c b/gnu/lib/libgmp/mpz/ior.c
new file mode 100644
index 0000000..77facfd
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/ior.c
@@ -0,0 +1,243 @@
+/* mpz_ior -- Logical inclusive or.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_ior (mpz_ptr res, mpz_srcptr op1, mpz_srcptr op2)
+#else
+mpz_ior (res, op1, op2)
+ mpz_ptr res;
+ mpz_srcptr op1;
+ mpz_srcptr op2;
+#endif
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size_t op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size_t res_size;
+ mp_size_t i;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ op1_size = op1->_mp_size;
+ op2_size = op2->_mp_size;
+
+ op1_ptr = op1->_mp_d;
+ op2_ptr = op2->_mp_d;
+ res_ptr = res->_mp_d;
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ if (op1_size >= op2_size)
+ {
+ if (res->_mp_alloc < op1_size)
+ {
+ _mpz_realloc (res, op1_size);
+ op1_ptr = op1->_mp_d;
+ op2_ptr = op2->_mp_d;
+ res_ptr = res->_mp_d;
+ }
+
+ if (res_ptr != op1_ptr)
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op1_size;
+ }
+ else
+ {
+ if (res->_mp_alloc < op2_size)
+ {
+ _mpz_realloc (res, op2_size);
+ op1_ptr = op1->_mp_d;
+ op2_ptr = op2->_mp_d;
+ res_ptr = res->_mp_d;
+ }
+
+ if (res_ptr != op2_ptr)
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ for (i = op1_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op2_size;
+ }
+
+ res->_mp_size = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ {
+ /* Fall through to the code at the end of the function. */
+ }
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx;
+ mp_limb_t cy;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) | (-OP2)) = -(~(OP1 - 1) | ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) | ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) & (OP2 - 1)) + 1 */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ res_size = MIN (op1_size, op2_size);
+
+ /* Possible optimization: Decrease mpn_sub precision,
+ as we won't use the entire res of both. */
+ opx = (mp_ptr) TMP_ALLOC (res_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op1_ptr, res_size, (mp_limb_t) 1);
+ op1_ptr = opx;
+
+ opx = (mp_ptr) TMP_ALLOC (res_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op2_ptr, res_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ if (res->_mp_alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->_mp_d;
+ /* Don't re-read OP1_PTR and OP2_PTR. They point to
+ temporary space--never to the space RES->_mp_D used
+ to point to before reallocation. */
+ }
+
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ if (res_size != 0)
+ {
+ /* Second loop computes the real result. */
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & op2_ptr[i];
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ res->_mp_size = -res_size;
+ TMP_FREE (marker);
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 | OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 | -OP2. */
+ {mpz_srcptr t = op1; op1 = op2; op2 = t;}
+ {mp_srcptr t = op1_ptr; op1_ptr = op2_ptr; op2_ptr = t;}
+ {mp_size_t t = op1_size; op1_size = op2_size; op2_size = t;}
+ }
+ }
+
+ {
+ mp_ptr opx;
+ mp_limb_t cy;
+ mp_size_t res_alloc;
+ mp_size_t count;
+
+ /* Operand 2 negative, so will be the result.
+ -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) =
+ = ~(OP1 | ~(OP2 - 1)) + 1 =
+ = (~OP1 & (OP2 - 1)) + 1 */
+
+ op2_size = -op2_size;
+
+ res_alloc = op2_size;
+
+ opx = (mp_ptr) TMP_ALLOC (op2_size * BYTES_PER_MP_LIMB);
+ mpn_sub_1 (opx, op2_ptr, op2_size, (mp_limb_t) 1);
+ op2_ptr = opx;
+
+ if (res->_mp_alloc < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ op1_ptr = op1->_mp_d;
+ res_ptr = res->_mp_d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->_mp_D used to point to before reallocation. */
+ }
+
+ if (op1_size >= op2_size)
+ {
+ /* We can just ignore the part of OP1 that stretches above OP2,
+ because the result limbs are zero there. */
+
+ /* First loop finds the size of the result. */
+ for (i = op2_size - 1; i >= 0; i--)
+ if ((~op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ count = res_size;
+ }
+ else
+ {
+ res_size = op2_size;
+
+ /* Copy the part of OP2 that stretches above OP1, to RES. */
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size, op2_size - op1_size);
+ count = op1_size;
+ }
+
+ if (res_size != 0)
+ {
+ /* Second loop computes the real result. */
+ for (i = count - 1; i >= 0; i--)
+ res_ptr[i] = ~op1_ptr[i] & op2_ptr[i];
+
+ cy = mpn_add_1 (res_ptr, res_ptr, res_size, (mp_limb_t) 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ res->_mp_size = -res_size;
+ }
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/iset.c b/gnu/lib/libgmp/mpz/iset.c
new file mode 100644
index 0000000..c8a17dc
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/iset.c
@@ -0,0 +1,49 @@
+/* mpz_init_set (src_integer) -- Make a new multiple precision number with
+ a value copied from SRC_INTEGER.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_init_set (mpz_ptr w, mpz_srcptr u)
+#else
+mpz_init_set (w, u)
+ mpz_ptr w;
+ mpz_srcptr u;
+#endif
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+
+ usize = u->_mp_size;
+ size = ABS (usize);
+
+ w->_mp_alloc = MAX (size, 1);
+ w->_mp_d = (mp_ptr) (*_mp_allocate_func) (w->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ MPN_COPY (wp, up, size);
+ w->_mp_size = usize;
+}
diff --git a/gnu/lib/libgmp/mpz/iset_d.c b/gnu/lib/libgmp/mpz/iset_d.c
new file mode 100644
index 0000000..41e5c4f
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/iset_d.c
@@ -0,0 +1,39 @@
+/* mpz_init_set_d(integer, val) -- Initialize and assign INTEGER with a double
+ value VAL.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_init_set_d (mpz_ptr dest, double val)
+#else
+mpz_init_set_d (dest, val)
+ mpz_ptr dest;
+ double val;
+#endif
+{
+ dest->_mp_alloc = 1;
+ dest->_mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ dest->_mp_size = 0;
+ mpz_set_d (dest, val);
+}
diff --git a/gnu/lib/libgmp/mpz/iset_si.c b/gnu/lib/libgmp/mpz/iset_si.c
new file mode 100644
index 0000000..af51f05
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/iset_si.c
@@ -0,0 +1,49 @@
+/* mpz_init_set_si(val) -- Make a new multiple precision number with
+ value val.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_init_set_si (mpz_ptr x, signed long int val)
+#else
+mpz_init_set_si (x, val)
+ mpz_ptr x;
+ signed long int val;
+#endif
+{
+ x->_mp_alloc = 1;
+ x->_mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ if (val > 0)
+ {
+ x->_mp_d[0] = val;
+ x->_mp_size = 1;
+ }
+ else if (val < 0)
+ {
+ x->_mp_d[0] = -val;
+ x->_mp_size = -1;
+ }
+ else
+ x->_mp_size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz/iset_str.c b/gnu/lib/libgmp/mpz/iset_str.c
new file mode 100644
index 0000000..e04ad5d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/iset_str.c
@@ -0,0 +1,44 @@
+/* mpz_init_set_str(string, base) -- Convert the \0-terminated string
+ STRING in base BASE to a multiple precision integer. Return a MP_INT
+ structure representing the integer. Allow white space in the
+ string. If BASE == 0 determine the base in the C standard way,
+ i.e. 0xhh...h means base 16, 0oo...o means base 8, otherwise
+ assume base 10.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpz_init_set_str (mpz_ptr x, const char *str, int base)
+#else
+mpz_init_set_str (x, str, base)
+ mpz_ptr x;
+ const char *str;
+ int base;
+#endif
+{
+ x->_mp_alloc = 1;
+ x->_mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+
+ return mpz_set_str (x, str, base);
+}
diff --git a/gnu/lib/libgmp/mpz/iset_ui.c b/gnu/lib/libgmp/mpz/iset_ui.c
new file mode 100644
index 0000000..dc39f59
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/iset_ui.c
@@ -0,0 +1,39 @@
+/* mpz_init_set_ui(val) -- Make a new multiple precision number with
+ value val.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_init_set_ui (mpz_ptr x, unsigned long int val)
+#else
+mpz_init_set_ui (x, val)
+ mpz_ptr x;
+ unsigned long int val;
+#endif
+{
+ x->_mp_alloc = 1;
+ x->_mp_d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB);
+ x->_mp_d[0] = val;
+ x->_mp_size = val != 0;
+}
diff --git a/gnu/lib/libgmp/mpz/jacobi.c b/gnu/lib/libgmp/mpz/jacobi.c
new file mode 100644
index 0000000..409f622
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/jacobi.c
@@ -0,0 +1,53 @@
+/* mpz_jacobi (op1, op2).
+ Contributed by Bennet Yee (bsy) at Carnegie-Mellon University
+
+Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+
+/* Precondition: both p and q are positive */
+
+int
+#if __STDC__
+mpz_jacobi (mpz_srcptr pi, mpz_srcptr qi)
+#else
+mpz_jacobi (pi, qi)
+ mpz_srcptr pi, qi;
+#endif
+{
+#if GCDCHECK
+ int retval;
+ mpz_t gcdval;
+
+ mpz_init (gcdval);
+ mpz_gcd (gcdval, pi, qi);
+ if (!mpz_cmp_ui (gcdval, 1L))
+ {
+ /* J(ab,cb) = J(ab,c)J(ab,b) = J(ab,c)J(0,b) = J(ab,c)*0 */
+ retval = 0;
+ }
+ else
+ retval = mpz_legendre (pi, qi);
+ mpz_clear (gcdval);
+ return retval;
+#else
+ return mpz_legendre (pi, qi);
+#endif
+}
diff --git a/gnu/lib/libgmp/mpz/legendre.c b/gnu/lib/libgmp/mpz/legendre.c
new file mode 100644
index 0000000..4de16a6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/legendre.c
@@ -0,0 +1,184 @@
+/* mpz_legendre (op1, op2).
+ Contributed by Bennet Yee (bsy) at Carnegie-Mellon University
+
+Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+
+#if defined (DEBUG)
+#include <stdio.h>
+#endif
+
+/* Precondition: both p and q are positive */
+
+int
+#if __STDC__
+mpz_legendre (mpz_srcptr pi, mpz_srcptr qi)
+#else
+mpz_legendre (pi, qi)
+mpz_srcptr pi, qi;
+#endif
+{
+ mpz_t p, q, qdiv2;
+#ifdef Q_MINUS_1
+ mpz_t q_minus_1;
+#endif
+ mpz_ptr mtmp;
+ register mpz_ptr pptr, qptr;
+ register int retval = 1;
+ register unsigned long int s;
+
+ pptr = p;
+ mpz_init_set (pptr, pi);
+ qptr = q;
+ mpz_init_set (qptr, qi);
+
+#ifdef Q_MINUS_1
+ mpz_init (q_minus_1);
+#endif
+ mpz_init (qdiv2);
+
+tail_recurse2:
+#ifdef DEBUG
+ printf ("tail_recurse2: p=");
+ mpz_out_str (stdout, 10, pptr);
+ printf ("\nq=");
+ mpz_out_str (stdout, 10, qptr);
+ putchar ('\n');
+#endif
+ s = mpz_scan1 (qptr, 0);
+ if (s) mpz_tdiv_q_2exp (qptr, qptr, s); /* J(a,2) = 1 */
+#ifdef DEBUG
+ printf ("2 factor decomposition: p=");
+ mpz_out_str (stdout, 10, pptr);
+ printf ("\nq=");
+ mpz_out_str (stdout, 10, qptr);
+ putchar ('\n');
+#endif
+ /* postcondition q odd */
+ if (!mpz_cmp_ui (qptr, 1L)) /* J(a,1) = 1 */
+ goto done;
+ mpz_mod (pptr, pptr, qptr); /* J(a,q) = J(b,q) when a == b mod q */
+#ifdef DEBUG
+ printf ("mod out by q: p=");
+ mpz_out_str (stdout, 10, pptr);
+ printf ("\nq=");
+ mpz_out_str (stdout, 10, qptr);
+ putchar ('\n');
+#endif
+ /* quick calculation to get approximate size first */
+ /* precondition: p < q */
+ if ((mpz_sizeinbase (pptr, 2) + 1 >= mpz_sizeinbase (qptr,2))
+ && (mpz_tdiv_q_2exp (qdiv2, qptr, 1L), mpz_cmp (pptr, qdiv2) > 0))
+ {
+ /* p > q/2 */
+ mpz_sub (pptr, qptr, pptr);
+ /* J(-1,q) = (-1)^((q-1)/2), q odd */
+ if (mpz_get_ui (qptr) & 2)
+ retval = -retval;
+ }
+ /* p < q/2 */
+#ifdef Q_MINUS_1
+ mpz_sub_ui (q_minus_q, qptr, 1L);
+#endif
+tail_recurse: /* we use tail_recurse only if q has not changed */
+#ifdef DEBUG
+ printf ("tail_recurse1: p=");
+ mpz_out_str (stdout, 10, pptr);
+ printf ("\nq=");
+ mpz_out_str (stdout, 10, qptr);
+ putchar ('\n');
+#endif
+ /*
+ * J(0,q) = 0
+ * this occurs only if gcd(p,q) != 1 which is never true for
+ * Legendre function.
+ */
+ if (!mpz_cmp_ui (pptr, 0L))
+ {
+ retval = 0;
+ goto done;
+ }
+
+ if (!mpz_cmp_ui (pptr, 1L))
+ {
+ /* J(1,q) = 1 */
+ /* retval *= 1; */
+ goto done;
+ }
+#ifdef Q_MINUS_1
+ if (!mpz_cmp (pptr, q_minus_1))
+ {
+ /* J(-1,q) = (-1)^((q-1)/2) */
+ if (mpz_get_ui (qptr) & 2)
+ retval = -retval;
+ /* else retval *= 1; */
+ goto done;
+ }
+#endif
+ /*
+ * we do not handle J(xy,q) except for x==2
+ * since we do not want to factor
+ */
+ if ((s = mpz_scan1 (pptr, 0)) != 0)
+ {
+ /*
+ * J(2,q) = (-1)^((q^2-1)/8)
+ *
+ * Note that q odd guarantees that q^2-1 is divisible by 8:
+ * Let a: q=2a+1. q^2 = 4a^2+4a+1, (q^2-1)/8 = a(a+1)/2, qed
+ *
+ * Now, note that this means that the low two bits of _a_
+ * (or the low bits of q shifted over by 1 determines
+ * the factor).
+ */
+ mpz_tdiv_q_2exp (pptr, pptr, s);
+
+ /* even powers of 2 gives J(2,q)^{2n} = 1 */
+ if (s & 1)
+ {
+ s = mpz_get_ui (qptr) >> 1;
+ s = s * (s + 1);
+ if (s & 2)
+ retval = -retval;
+ }
+ goto tail_recurse;
+ }
+ /*
+ * we know p is odd since we have cast out 2s
+ * precondition that q is odd guarantees both odd.
+ *
+ * quadratic reciprocity
+ * J(p,q) = (-1)^((p-1)(q-1)/4) * J(q,p)
+ */
+ if ((s = mpz_scan1 (pptr, 1)) <= 2 && (s + mpz_scan1 (qptr, 1)) <= 2)
+ retval = -retval;
+
+ mtmp = pptr; pptr = qptr; qptr = mtmp;
+ goto tail_recurse2;
+done:
+ mpz_clear (p);
+ mpz_clear (q);
+ mpz_clear (qdiv2);
+#ifdef Q_MINUS_1
+ mpz_clear (q_minus_1);
+#endif
+ return retval;
+}
diff --git a/gnu/lib/libgmp/mpz/mod.c b/gnu/lib/libgmp/mpz/mod.c
new file mode 100644
index 0000000..b2b8b39
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/mod.c
@@ -0,0 +1,63 @@
+/* mpz_mod -- The mathematical mod function.
+
+Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_mod (mpz_ptr rem, mpz_srcptr dividend, mpz_srcptr divisor)
+#else
+mpz_mod (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ mpz_srcptr divisor;
+#endif
+{
+ mp_size_t divisor_size = divisor->_mp_size;
+ mpz_t temp_divisor; /* N.B.: lives until function returns! */
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+
+ /* We need the original value of the divisor after the remainder has been
+ preliminary calculated. We have to copy it to temporary space if it's
+ the same variable as REM. */
+ if (rem == divisor)
+ {
+ MPZ_TMP_INIT (temp_divisor, ABS (divisor_size));
+ mpz_set (temp_divisor, divisor);
+ divisor = temp_divisor;
+ }
+
+ mpz_tdiv_r (rem, dividend, divisor);
+
+ if (rem->_mp_size != 0)
+ {
+ if (dividend->_mp_size < 0)
+ if (divisor->_mp_size < 0)
+ mpz_sub (rem, rem, divisor);
+ else
+ mpz_add (rem, rem, divisor);
+ }
+
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/mul.c b/gnu/lib/libgmp/mpz/mul.c
new file mode 100644
index 0000000..47ce8e3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/mul.c
@@ -0,0 +1,127 @@
+/* mpz_mul -- Multiply two integers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_mul (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_mul (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+mult (mpz_srcptr u, mpz_srcptr v, mpz_ptr w)
+#else
+mult (u, v, w)
+ mpz_srcptr u;
+ mpz_srcptr v;
+ mpz_ptr w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize = v->_mp_size;
+ mp_size_t wsize;
+ mp_size_t sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me = NULL;
+ size_t free_me_size;
+ mp_limb_t cy_limb;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ /* Swap U and V. */
+ {const __mpz_struct *t = u; u = v; v = t;}
+ {mp_size_t t = usize; usize = vsize; vsize = t;}
+ }
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ wp = w->_mp_d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->_mp_alloc < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = w->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (wp, w->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ w->_mp_alloc = wsize;
+ wp = (mp_ptr) (*_mp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
+ w->_mp_d = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ if (vsize == 0)
+ {
+ wsize = 0;
+ }
+ else
+ {
+ cy_limb = mpn_mul (wp, up, usize, vp, vsize);
+ wsize = usize + vsize;
+ wsize -= cy_limb == 0;
+ }
+
+ w->_mp_size = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/mul_2exp.c b/gnu/lib/libgmp/mpz/mul_2exp.c
new file mode 100644
index 0000000..4d66a98
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/mul_2exp.c
@@ -0,0 +1,76 @@
+/* mpz_mul_2exp -- Multiply a bignum by 2**CNT
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_mul_2exp (mpz_ptr w, mpz_srcptr u, unsigned long int cnt)
+#else
+mpz_mul_2exp (w, u, cnt)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int cnt;
+#endif
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t abs_usize = ABS (usize);
+ mp_size_t wsize;
+ mp_size_t limb_cnt;
+ mp_ptr wp;
+ mp_limb_t wlimb;
+
+ if (usize == 0)
+ {
+ w->_mp_size = 0;
+ return;
+ }
+
+ limb_cnt = cnt / BITS_PER_MP_LIMB;
+ wsize = abs_usize + limb_cnt + 1;
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ wp = w->_mp_d;
+ wsize = abs_usize + limb_cnt;
+
+ cnt %= BITS_PER_MP_LIMB;
+ if (cnt != 0)
+ {
+ wlimb = mpn_lshift (wp + limb_cnt, u->_mp_d, abs_usize, cnt);
+ if (wlimb != 0)
+ {
+ wp[wsize] = wlimb;
+ wsize++;
+ }
+ }
+ else
+ {
+ MPN_COPY_DECR (wp + limb_cnt, u->_mp_d, abs_usize);
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ mpn_lshift, not to lose for U == W. */
+ MPN_ZERO (wp, limb_cnt);
+
+ w->_mp_size = usize >= 0 ? wsize : -wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/mul_ui.c b/gnu/lib/libgmp/mpz/mul_ui.c
new file mode 100644
index 0000000..f1f7269
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/mul_ui.c
@@ -0,0 +1,64 @@
+/* mpz_mul_ui(product, multiplier, small_multiplicand) -- Set
+ PRODUCT to MULTIPLICATOR times SMALL_MULTIPLICAND.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_mul_ui (mpz_ptr prod, mpz_srcptr mult, unsigned long int small_mult)
+#else
+mpz_mul_ui (prod, mult, small_mult)
+ mpz_ptr prod;
+ mpz_srcptr mult;
+ unsigned long int small_mult;
+#endif
+{
+ mp_size_t size = mult->_mp_size;
+ mp_size_t sign_product = size;
+ mp_limb_t cy;
+ mp_size_t prod_size;
+ mp_ptr prod_ptr;
+
+ size = ABS (size);
+
+ if (size == 0 || small_mult == 0)
+ {
+ prod->_mp_size = 0;
+ return;
+ }
+
+ prod_size = size + 1;
+ if (prod->_mp_alloc < prod_size)
+ _mpz_realloc (prod, prod_size);
+
+ prod_ptr = prod->_mp_d;
+
+ cy = mpn_mul_1 (prod_ptr, mult->_mp_d, size, (mp_limb_t) small_mult);
+ if (cy != 0)
+ {
+ prod_ptr[size] = cy;
+ size++;
+ }
+
+ prod->_mp_size = sign_product >= 0 ? size : -size;
+}
diff --git a/gnu/lib/libgmp/mpz/neg.c b/gnu/lib/libgmp/mpz/neg.c
new file mode 100644
index 0000000..0b48e5c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/neg.c
@@ -0,0 +1,53 @@
+/* mpz_neg(mpz_ptr dst, mpz_ptr src) -- Assign the negated value of SRC to DST.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_neg (mpz_ptr w, mpz_srcptr u)
+#else
+mpz_neg (w, u)
+ mpz_ptr w;
+ mpz_srcptr u;
+#endif
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+
+ usize = u->_mp_size;
+
+ if (u != w)
+ {
+ size = ABS (usize);
+
+ if (w->_mp_alloc < size)
+ _mpz_realloc (w, size);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ MPN_COPY (wp, up, size);
+ }
+
+ w->_mp_size = -usize;
+}
diff --git a/gnu/lib/libgmp/mpz/out_raw.c b/gnu/lib/libgmp/mpz/out_raw.c
new file mode 100644
index 0000000..35d311b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/out_raw.c
@@ -0,0 +1,89 @@
+/* mpz_out_raw -- Output a mpz_t in binary. Use an endianess and word size
+ independent format.
+
+Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpz_out_raw (FILE *stream, mpz_srcptr x)
+#else
+mpz_out_raw (stream, x)
+ FILE *stream;
+ mpz_srcptr x;
+#endif
+{
+ int i;
+ mp_size_t s;
+ mp_size_t xsize = ABS (x->_mp_size);
+ mp_srcptr xp = x->_mp_d;
+ mp_size_t out_bytesize;
+ mp_limb_t hi_limb;
+ int n_bytes_in_hi_limb;
+
+ if (stream == 0)
+ stream = stdout;
+
+ if (xsize == 0)
+ {
+ for (i = 4 - 1; i >= 0; i--)
+ fputc (0, stream);
+ return ferror (stream) ? 0 : 4;
+ }
+
+ hi_limb = xp[xsize - 1];
+ for (i = BYTES_PER_MP_LIMB - 1; i > 0; i--)
+ {
+ if ((hi_limb >> i * BITS_PER_CHAR) != 0)
+ break;
+ }
+ n_bytes_in_hi_limb = i + 1;
+ out_bytesize = BYTES_PER_MP_LIMB * (xsize - 1) + n_bytes_in_hi_limb;
+ if (x->_mp_size < 0)
+ out_bytesize = -out_bytesize;
+
+ /* Make the size 4 bytes on all machines, to make the format portable. */
+ for (i = 4 - 1; i >= 0; i--)
+ fputc ((out_bytesize >> (i * BITS_PER_CHAR)) % (1 << BITS_PER_CHAR),
+ stream);
+
+ /* Output from the most significant limb to the least significant limb,
+ with each limb also output in decreasing significance order. */
+
+ /* Output the most significant limb separately, since we will only
+ output some of its bytes. */
+ for (i = n_bytes_in_hi_limb - 1; i >= 0; i--)
+ fputc ((hi_limb >> (i * BITS_PER_CHAR)) % (1 << BITS_PER_CHAR), stream);
+
+ /* Output the remaining limbs. */
+ for (s = xsize - 2; s >= 0; s--)
+ {
+ mp_limb_t x_limb;
+
+ x_limb = xp[s];
+ for (i = BYTES_PER_MP_LIMB - 1; i >= 0; i--)
+ fputc ((x_limb >> (i * BITS_PER_CHAR)) % (1 << BITS_PER_CHAR), stream);
+ }
+ return ferror (stream) ? 0 : ABS (out_bytesize) + 4;
+}
diff --git a/gnu/lib/libgmp/mpz/out_str.c b/gnu/lib/libgmp/mpz/out_str.c
new file mode 100644
index 0000000..909f533
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/out_str.c
@@ -0,0 +1,108 @@
+/* mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec.
+ integer INTEGER in base BASE.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpz_out_str (FILE *stream, int base, mpz_srcptr x)
+#else
+mpz_out_str (stream, base, x)
+ FILE *stream;
+ int base;
+ mpz_srcptr x;
+#endif
+{
+ mp_ptr xp;
+ mp_size_t x_size = x->_mp_size;
+ unsigned char *str;
+ size_t str_size;
+ size_t i;
+ size_t written;
+ char *num_to_text;
+ TMP_DECL (marker);
+
+ if (stream == 0)
+ stream = stdout;
+
+ if (base >= 0)
+ {
+ if (base == 0)
+ base = 10;
+ num_to_text = "0123456789abcdefghijklmnopqrstuvwxyz";
+ }
+ else
+ {
+ base = -base;
+ num_to_text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ }
+
+ if (x_size == 0)
+ {
+ fputc ('0', stream);
+ return ferror (stream) ? 0 : 1;
+ }
+
+ written = 0;
+
+ if (x_size < 0)
+ {
+ fputc ('-', stream);
+ x_size = -x_size;
+ written = 1;
+ }
+
+ TMP_MARK (marker);
+ str_size = ((size_t) (x_size * BITS_PER_MP_LIMB
+ * __mp_bases[base].chars_per_bit_exactly)) + 3;
+ str = (unsigned char *) TMP_ALLOC (str_size);
+
+ /* Move the number to convert into temporary space, since mpn_get_str
+ clobbers its argument + needs one extra high limb.... */
+ xp = (mp_ptr) TMP_ALLOC ((x_size + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (xp, x->_mp_d, x_size);
+
+ str_size = mpn_get_str (str, base, xp, x_size);
+
+ /* mpn_get_str might make some leading zeros. Skip them. */
+ while (*str == 0)
+ {
+ str_size--;
+ str++;
+ }
+
+ /* Translate to printable chars. */
+ for (i = 0; i < str_size; i++)
+ str[i] = num_to_text[str[i]];
+ str[str_size] = 0;
+
+ {
+ size_t fwret;
+ fwret = fwrite ((char *) str, 1, str_size, stream);
+ written += fwret;
+ }
+
+ TMP_FREE (marker);
+ return ferror (stream) ? 0 : written;
+}
diff --git a/gnu/lib/libgmp/mpz/perfsqr.c b/gnu/lib/libgmp/mpz/perfsqr.c
new file mode 100644
index 0000000..cdf1b5a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/perfsqr.c
@@ -0,0 +1,41 @@
+/* mpz_perfect_square_p(arg) -- Return non-zero if ARG is a perfect square,
+ zero otherwise.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#if __STDC__
+mpz_perfect_square_p (mpz_srcptr a)
+#else
+mpz_perfect_square_p (a)
+ mpz_srcptr a;
+#endif
+{
+ mp_size_t asize = a->_mp_size;
+
+ /* No negative numbers are perfect squares. */
+ if (asize < 0)
+ return 0;
+
+ return mpn_perfect_square_p (a->_mp_d, asize);
+}
diff --git a/gnu/lib/libgmp/mpz/popcount.c b/gnu/lib/libgmp/mpz/popcount.c
new file mode 100644
index 0000000..a979380
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/popcount.c
@@ -0,0 +1,42 @@
+/* mpz_popcount(mpz_ptr op) -- Population count of OP. If the operand is
+ negative, return ~0 (a novel representation of infinity).
+
+Copyright (C) 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_popcount (mpz_srcptr u)
+#else
+mpz_popcount (u)
+ mpz_srcptr u;
+#endif
+{
+ mp_size_t usize;
+
+ usize = u->_mp_size;
+
+ if ((usize) < 0)
+ return ~ (unsigned long int) 0;
+
+ return mpn_popcount (u->_mp_d, usize);
+}
diff --git a/gnu/lib/libgmp/mpz/pow_ui.c b/gnu/lib/libgmp/mpz/pow_ui.c
new file mode 100644
index 0000000..d8cf7a6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/pow_ui.c
@@ -0,0 +1,129 @@
+/* mpz_pow_ui(res, base, exp) -- Set RES to BASE**EXP.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#ifdef BERKELEY_MP
+#include "mp.h"
+#endif
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_pow_ui (mpz_ptr r, mpz_srcptr b, unsigned long int e)
+#else
+mpz_pow_ui (r, b, e)
+ mpz_ptr r;
+ mpz_srcptr b;
+ unsigned long int e;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+rpow (const MINT *b, signed short int e, MINT *r)
+#else
+rpow (b, e, r)
+ const MINT *b;
+ signed short int e;
+ MINT *r;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_ptr rp, bp, tp, xp;
+ mp_size_t rsize, bsize;
+ int cnt, i;
+ mp_limb_t blimb;
+ TMP_DECL (marker);
+
+ bsize = ABS (b->_mp_size);
+
+ /* Single out cases that give result == 0 or 1. These tests are here
+ to simplify the general code below, not to optimize. */
+ if (e == 0)
+ {
+ r->_mp_d[0] = 1;
+ r->_mp_size = 1;
+ return;
+ }
+ if (bsize == 0
+#ifdef BERKELEY_MP
+ || e < 0
+#endif
+ )
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ bp = b->_mp_d;
+
+ blimb = bp[bsize - 1];
+ if (bsize == 1 && blimb < 0x100)
+ {
+ /* Estimate space requirements accurately. Using the code from the
+ `else' path would over-estimate space requirements wildly. */
+ float lb = __mp_bases[blimb].chars_per_bit_exactly;
+ rsize = 2 + ((mp_size_t) (e / lb) / BITS_PER_MP_LIMB);
+ }
+ else
+ {
+ /* Over-estimate space requirements somewhat. */
+ count_leading_zeros (cnt, blimb);
+ rsize = bsize * e - cnt * e / BITS_PER_MP_LIMB + 1;
+ }
+
+ TMP_MARK (marker);
+
+ /* The two areas are used to alternatingly hold the input and recieve the
+ product for mpn_mul. (This scheme is used to fulfill the requirements
+ of mpn_mul; that the product space may not be the same as any of the
+ input operands.) */
+ rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+ count_leading_zeros (cnt, e);
+
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ mpn_mul_n (tp, rp, rp, rsize);
+ rsize = 2 * rsize;
+ rsize -= tp[rsize - 1] == 0;
+ xp = tp; tp = rp; rp = xp;
+
+ if ((e & ((mp_limb_t) 1 << i)) != 0)
+ {
+ rsize = rsize + bsize - (mpn_mul (tp, rp, rsize, bp, bsize) == 0);
+ xp = tp; tp = rp; rp = xp;
+ }
+ }
+
+ /* Now then we know the exact space requirements, reallocate if
+ necessary. */
+ if (r->_mp_alloc < rsize)
+ _mpz_realloc (r, rsize);
+
+ MPN_COPY (r->_mp_d, rp, rsize);
+ r->_mp_size = (e & 1) == 0 || b->_mp_size >= 0 ? rsize : -rsize;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/powm.c b/gnu/lib/libgmp/mpz/powm.c
new file mode 100644
index 0000000..5dcd1b1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/powm.c
@@ -0,0 +1,276 @@
+/* mpz_powm(res,base,exp,mod) -- Set RES to (base**exp) mod MOD.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_powm (mpz_ptr res, mpz_srcptr base, mpz_srcptr exp, mpz_srcptr mod)
+#else
+mpz_powm (res, base, exp, mod)
+ mpz_ptr res;
+ mpz_srcptr base;
+ mpz_srcptr exp;
+ mpz_srcptr mod;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+pow (mpz_srcptr base, mpz_srcptr exp, mpz_srcptr mod, mpz_ptr res)
+#else
+pow (base, exp, mod, res)
+ mpz_srcptr base;
+ mpz_srcptr exp;
+ mpz_srcptr mod;
+ mpz_ptr res;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_ptr rp, ep, mp, bp;
+ mp_size_t esize, msize, bsize, rsize;
+ mp_size_t size;
+ int mod_shift_cnt;
+ int negative_result;
+ mp_limb_t *free_me = NULL;
+ size_t free_me_size;
+ TMP_DECL (marker);
+
+ esize = ABS (exp->_mp_size);
+ msize = ABS (mod->_mp_size);
+ size = 2 * msize;
+
+ rp = res->_mp_d;
+ ep = exp->_mp_d;
+
+ if (msize == 0)
+ msize = 1 / msize; /* provoke a signal */
+
+ if (esize == 0)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
+ depending on if MOD equals 1. */
+ rp[0] = 1;
+ res->_mp_size = (msize == 1 && (mod->_mp_d)[0] == 1) ? 0 : 1;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Normalize MOD (i.e. make its most significant bit set) as required by
+ mpn_divmod. This will make the intermediate values in the calculation
+ slightly larger, but the correct result is obtained after a final
+ reduction using the original MOD value. */
+
+ mp = (mp_ptr) TMP_ALLOC (msize * BYTES_PER_MP_LIMB);
+ count_leading_zeros (mod_shift_cnt, mod->_mp_d[msize - 1]);
+ if (mod_shift_cnt != 0)
+ mpn_lshift (mp, mod->_mp_d, msize, mod_shift_cnt);
+ else
+ MPN_COPY (mp, mod->_mp_d, msize);
+
+ bsize = ABS (base->_mp_size);
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it. */
+
+ /* Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp = (mp_ptr) TMP_ALLOC ((bsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, base->_mp_d, bsize);
+ /* We don't care about the quotient, store it above the remainder,
+ at BP + MSIZE. */
+ mpn_divmod (bp + msize, bp, bsize, mp, msize);
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE (bp, bsize);
+ }
+ else
+ bp = base->_mp_d;
+
+ if (bsize == 0)
+ {
+ res->_mp_size = 0;
+ TMP_FREE (marker);
+ return;
+ }
+
+ if (res->_mp_alloc < size)
+ {
+ /* We have to allocate more space for RES. If any of the input
+ parameters are identical to RES, defer deallocation of the old
+ space. */
+
+ if (rp == ep || rp == mp || rp == bp)
+ {
+ free_me = rp;
+ free_me_size = res->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (rp, res->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ rp = (mp_ptr) (*_mp_allocate_func) (size * BYTES_PER_MP_LIMB);
+ res->_mp_alloc = size;
+ res->_mp_d = rp;
+ }
+ else
+ {
+ /* Make BASE, EXP and MOD not overlap with RES. */
+ if (rp == bp)
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ bp = (mp_ptr) TMP_ALLOC (bsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, rp, bsize);
+ }
+ if (rp == ep)
+ {
+ /* RES and EXP are identical. Allocate temp. space for EXP. */
+ ep = (mp_ptr) TMP_ALLOC (esize * BYTES_PER_MP_LIMB);
+ MPN_COPY (ep, rp, esize);
+ }
+ if (rp == mp)
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD. */
+ mp = (mp_ptr) TMP_ALLOC (msize * BYTES_PER_MP_LIMB);
+ MPN_COPY (mp, rp, msize);
+ }
+ }
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+
+ {
+ mp_size_t i;
+ mp_ptr xp = (mp_ptr) TMP_ALLOC (2 * (msize + 1) * BYTES_PER_MP_LIMB);
+ int c;
+ mp_limb_t e;
+ mp_limb_t carry_limb;
+
+ negative_result = (ep[0] & 1) && base->_mp_size < 0;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
+ c = BITS_PER_MP_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be necessary
+ with the overlap restrictions of mpn_divmod. With 50% probability
+ the result after this loop will be in the area originally pointed
+ by RP (==RES->_mp_d), and with 50% probability in the area originally
+ pointed to by XP. */
+
+ for (;;)
+ {
+ while (c != 0)
+ {
+ mp_ptr tp;
+ mp_size_t xsize;
+
+ mpn_mul_n (xp, rp, rp, rsize);
+ xsize = 2 * rsize;
+ if (xsize > msize)
+ {
+ mpn_divmod (xp + msize, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ if ((mp_limb_signed_t) e < 0)
+ {
+ mpn_mul (xp, rp, rsize, bp, bsize);
+ xsize = rsize + bsize;
+ if (xsize > msize)
+ {
+ mpn_divmod (xp + msize, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if (i < 0)
+ break;
+ e = ep[i];
+ c = BITS_PER_MP_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
+ steps. Adjust the result by reducing it with the original MOD.
+
+ Also make sure the result is put in RES->_mp_d (where it already
+ might be, see above). */
+
+ if (mod_shift_cnt != 0)
+ {
+ carry_limb = mpn_lshift (res->_mp_d, rp, rsize, mod_shift_cnt);
+ rp = res->_mp_d;
+ if (carry_limb != 0)
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else
+ {
+ MPN_COPY (res->_mp_d, rp, rsize);
+ rp = res->_mp_d;
+ }
+
+ if (rsize >= msize)
+ {
+ mpn_divmod (rp + msize, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if (mod_shift_cnt != 0)
+ mpn_rshift (rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+ }
+
+ if (negative_result && rsize != 0)
+ {
+ if (mod_shift_cnt != 0)
+ mpn_rshift (mp, mp, msize, mod_shift_cnt);
+ mpn_sub (rp, mp, msize, rp, rsize);
+ rsize = msize;
+ MPN_NORMALIZE (rp, rsize);
+ }
+ res->_mp_size = rsize;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/powm_ui.c b/gnu/lib/libgmp/mpz/powm_ui.c
new file mode 100644
index 0000000..596815a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/powm_ui.c
@@ -0,0 +1,234 @@
+/* mpz_powm_ui(res,base,exp,mod) -- Set RES to (base**exp) mod MOD.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_powm_ui (mpz_ptr res, mpz_srcptr base, unsigned long int exp, mpz_srcptr mod)
+#else
+mpz_powm_ui (res, base, exp, mod)
+ mpz_ptr res;
+ mpz_srcptr base;
+ unsigned long int exp;
+ mpz_srcptr mod;
+#endif
+{
+ mp_ptr rp, mp, bp;
+ mp_size_t msize, bsize, rsize;
+ mp_size_t size;
+ int mod_shift_cnt;
+ int negative_result;
+ mp_limb_t *free_me = NULL;
+ size_t free_me_size;
+ TMP_DECL (marker);
+
+ msize = ABS (mod->_mp_size);
+ size = 2 * msize;
+
+ rp = res->_mp_d;
+
+ if (msize == 0)
+ msize = 1 / msize; /* provoke a signal */
+
+ if (exp == 0)
+ {
+ rp[0] = 1;
+ res->_mp_size = (msize == 1 && (mod->_mp_d)[0] == 1) ? 0 : 1;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ /* Normalize MOD (i.e. make its most significant bit set) as required by
+ mpn_divmod. This will make the intermediate values in the calculation
+ slightly larger, but the correct result is obtained after a final
+ reduction using the original MOD value. */
+
+ mp = (mp_ptr) TMP_ALLOC (msize * BYTES_PER_MP_LIMB);
+ count_leading_zeros (mod_shift_cnt, mod->_mp_d[msize - 1]);
+ if (mod_shift_cnt != 0)
+ mpn_lshift (mp, mod->_mp_d, msize, mod_shift_cnt);
+ else
+ MPN_COPY (mp, mod->_mp_d, msize);
+
+ bsize = ABS (base->_mp_size);
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it. */
+
+ /* Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp = (mp_ptr) TMP_ALLOC ((bsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, base->_mp_d, bsize);
+ /* We don't care about the quotient, store it above the remainder,
+ at BP + MSIZE. */
+ mpn_divmod (bp + msize, bp, bsize, mp, msize);
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE (bp, bsize);
+ }
+ else
+ bp = base->_mp_d;
+
+ if (bsize == 0)
+ {
+ res->_mp_size = 0;
+ TMP_FREE (marker);
+ return;
+ }
+
+ if (res->_mp_alloc < size)
+ {
+ /* We have to allocate more space for RES. If any of the input
+ parameters are identical to RES, defer deallocation of the old
+ space. */
+
+ if (rp == mp || rp == bp)
+ {
+ free_me = rp;
+ free_me_size = res->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (rp, res->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ rp = (mp_ptr) (*_mp_allocate_func) (size * BYTES_PER_MP_LIMB);
+ res->_mp_alloc = size;
+ res->_mp_d = rp;
+ }
+ else
+ {
+ /* Make BASE, EXP and MOD not overlap with RES. */
+ if (rp == bp)
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ bp = (mp_ptr) TMP_ALLOC (bsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, rp, bsize);
+ }
+ if (rp == mp)
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD. */
+ mp = (mp_ptr) TMP_ALLOC (msize * BYTES_PER_MP_LIMB);
+ MPN_COPY (mp, rp, msize);
+ }
+ }
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+
+ {
+ mp_ptr xp = (mp_ptr) TMP_ALLOC (2 * (msize + 1) * BYTES_PER_MP_LIMB);
+ int c;
+ mp_limb_t e;
+ mp_limb_t carry_limb;
+
+ negative_result = (exp & 1) && base->_mp_size < 0;
+
+ e = exp;
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
+ c = BITS_PER_MP_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be necessary
+ with the overlap restrictions of mpn_divmod. With 50% probability
+ the result after this loop will be in the area originally pointed
+ by RP (==RES->_mp_d), and with 50% probability in the area originally
+ pointed to by XP. */
+
+ while (c != 0)
+ {
+ mp_ptr tp;
+ mp_size_t xsize;
+
+ mpn_mul_n (xp, rp, rp, rsize);
+ xsize = 2 * rsize;
+ if (xsize > msize)
+ {
+ mpn_divmod (xp + msize, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ if ((mp_limb_signed_t) e < 0)
+ {
+ mpn_mul (xp, rp, rsize, bp, bsize);
+ xsize = rsize + bsize;
+ if (xsize > msize)
+ {
+ mpn_divmod (xp + msize, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
+ steps. Adjust the result by reducing it with the original MOD.
+
+ Also make sure the result is put in RES->_mp_d (where it already
+ might be, see above). */
+
+ if (mod_shift_cnt != 0)
+ {
+ carry_limb = mpn_lshift (res->_mp_d, rp, rsize, mod_shift_cnt);
+ rp = res->_mp_d;
+ if (carry_limb != 0)
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else
+ {
+ MPN_COPY (res->_mp_d, rp, rsize);
+ rp = res->_mp_d;
+ }
+
+ if (rsize >= msize)
+ {
+ mpn_divmod (rp + msize, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if (mod_shift_cnt != 0)
+ mpn_rshift (rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+ }
+
+ res->_mp_size = negative_result == 0 ? rsize : -rsize;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/pprime_p.c b/gnu/lib/libgmp/mpz/pprime_p.c
new file mode 100644
index 0000000..494de14
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/pprime_p.c
@@ -0,0 +1,115 @@
+/* mpz_probab_prime_p --
+ An implementation of the probabilistic primality test found in Knuth's
+ Seminumerical Algorithms book. If the function mpz_probab_prime_p()
+ returns 0 then n is not prime. If it returns 1, then n is 'probably'
+ prime. The probability of a false positive is (1/4)**reps, where
+ reps is the number of internal passes of the probabilistic algorithm.
+ Knuth indicates that 25 passes are reasonable.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+Contributed by John Amanatides.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+
+static int
+possibly_prime (n, n_minus_1, x, y, q, k)
+ mpz_srcptr n;
+ mpz_srcptr n_minus_1;
+ mpz_ptr x;
+ mpz_ptr y;
+ mpz_srcptr q;
+ unsigned long int k;
+{
+ unsigned long int i;
+
+ /* find random x s.t. 1 < x < n */
+ do
+ {
+ mpz_random (x, mpz_size (n));
+ mpz_mmod (x, x, n);
+ }
+ while (mpz_cmp_ui (x, 1L) <= 0);
+
+ mpz_powm (y, x, q, n);
+
+ if (mpz_cmp_ui (y, 1L) == 0 || mpz_cmp (y, n_minus_1) == 0)
+ return 1;
+
+ for (i = 1; i < k; i++)
+ {
+ mpz_powm_ui (y, y, 2L, n);
+ if (mpz_cmp (y, n_minus_1) == 0)
+ return 1;
+ if (mpz_cmp_ui (y, 1L) == 0)
+ return 0;
+ }
+ return 0;
+}
+
+int
+#if __STDC__
+mpz_probab_prime_p (mpz_srcptr m, int reps)
+#else
+mpz_probab_prime_p (m, reps)
+ mpz_srcptr m;
+ int reps;
+#endif
+{
+ mpz_t n, n_minus_1, x, y, q;
+ int i, is_prime;
+ unsigned long int k;
+
+ mpz_init (n);
+ /* Take the absolute value of M, to handle positive and negative primes. */
+ mpz_abs (n, m);
+
+ if (mpz_cmp_ui (n, 3L) <= 0)
+ {
+ mpz_clear (n);
+ return mpz_cmp_ui (n, 1L) > 0;
+ }
+
+ if ((mpz_get_ui (n) & 1) == 0)
+ {
+ mpz_clear (n);
+ return 0; /* even */
+ }
+
+ mpz_init (n_minus_1);
+ mpz_sub_ui (n_minus_1, n, 1L);
+ mpz_init (x);
+ mpz_init (y);
+
+ /* find q and k, s.t. n = 1 + 2**k * q */
+ mpz_init_set (q, n_minus_1);
+ k = mpz_scan1 (q, 0);
+ mpz_tdiv_q_2exp (q, q, k);
+
+ is_prime = 1;
+ for (i = 0; i < reps && is_prime; i++)
+ is_prime &= possibly_prime (n, n_minus_1, x, y, q, k);
+
+ mpz_clear (n_minus_1);
+ mpz_clear (n);
+ mpz_clear (x);
+ mpz_clear (y);
+ mpz_clear (q);
+ return is_prime;
+}
diff --git a/gnu/lib/libgmp/mpz/random.c b/gnu/lib/libgmp/mpz/random.c
new file mode 100644
index 0000000..ab41eef
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/random.c
@@ -0,0 +1,56 @@
+/* mpz_random -- Generate a random mpz_t of specified size.
+ This function is non-portable and generates poor random numbers.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void
+#if __STDC__
+mpz_random (mpz_ptr x, mp_size_t size)
+#else
+mpz_random (x, size)
+ mpz_ptr x;
+ mp_size_t size;
+#endif
+{
+ mp_size_t i;
+ mp_limb_t ran;
+ mp_ptr xp;
+ mp_size_t abs_size;
+
+ abs_size = ABS (size);
+
+ if (x->_mp_alloc < abs_size)
+ _mpz_realloc (x, abs_size);
+
+ xp = x->_mp_d;
+
+ for (i = 0; i < abs_size; i++)
+ {
+ ran = urandom ();
+ xp[i] = ran;
+ }
+
+ MPN_NORMALIZE (xp, abs_size);
+ x->_mp_size = size < 0 ? -abs_size : abs_size;
+}
diff --git a/gnu/lib/libgmp/mpz/random2.c b/gnu/lib/libgmp/mpz/random2.c
new file mode 100644
index 0000000..725a8b4
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/random2.c
@@ -0,0 +1,48 @@
+/* mpz_random2 -- Generate a positive random mpz_t of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Meant for testing of other MP routines.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_random2 (mpz_ptr x, mp_size_t size)
+#else
+mpz_random2 (x, size)
+ mpz_ptr x;
+ mp_size_t size;
+#endif
+{
+ mp_size_t abs_size;
+
+ abs_size = ABS (size);
+ if (abs_size != 0)
+ {
+ if (x->_mp_alloc < abs_size)
+ _mpz_realloc (x, abs_size);
+
+ mpn_random2 (x->_mp_d, abs_size);
+ }
+
+ x->_mp_size = size;
+}
diff --git a/gnu/lib/libgmp/mpz/realloc.c b/gnu/lib/libgmp/mpz/realloc.c
new file mode 100644
index 0000000..2c2a5da
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/realloc.c
@@ -0,0 +1,52 @@
+/* _mpz_realloc -- make the mpz_t have NEW_SIZE digits allocated.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void *
+#if __STDC__
+_mpz_realloc (mpz_ptr m, mp_size_t new_size)
+#else
+_mpz_realloc (m, new_size)
+ mpz_ptr m;
+ mp_size_t new_size;
+#endif
+{
+ /* Never allocate zero space. */
+ if (new_size == 0)
+ new_size = 1;
+
+ m->_mp_d = (mp_ptr) (*_mp_reallocate_func) (m->_mp_d,
+ m->_mp_alloc * BYTES_PER_MP_LIMB,
+ new_size * BYTES_PER_MP_LIMB);
+ m->_mp_alloc = new_size;
+
+#if 0
+ /* This might break some code that reads the size field after
+ reallocation, in the case the reallocated destination and a
+ source argument are identical. */
+ if (ABS (m->_mp_size) > new_size)
+ m->_mp_size = 0;
+#endif
+
+ return (void *) m->_mp_d;
+}
diff --git a/gnu/lib/libgmp/mpz/scan0.c b/gnu/lib/libgmp/mpz/scan0.c
new file mode 100644
index 0000000..8e45aa3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/scan0.c
@@ -0,0 +1,35 @@
+/* mpz_scan0(op, startbit) -- Scan for the next set bit, starting at startbit.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_scan0 (mpz_srcptr u, unsigned long int starting_bit)
+#else
+mpz_scan0 (u, starting_bit)
+ mpz_srcptr u;
+ unsigned long int starting_bit;
+#endif
+{
+ return mpn_scan0 (u->_mp_d, starting_bit);
+}
diff --git a/gnu/lib/libgmp/mpz/scan1.c b/gnu/lib/libgmp/mpz/scan1.c
new file mode 100644
index 0000000..6ecb0aa
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/scan1.c
@@ -0,0 +1,35 @@
+/* mpz_scan1(op, startbit) -- Scan for the next set bit, starting at startbit.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#if __STDC__
+mpz_scan1 (mpz_srcptr u, unsigned long int starting_bit)
+#else
+mpz_scan1 (u, starting_bit)
+ mpz_srcptr u;
+ unsigned long int starting_bit;
+#endif
+{
+ return mpn_scan1 (u->_mp_d, starting_bit);
+}
diff --git a/gnu/lib/libgmp/mpz/set.c b/gnu/lib/libgmp/mpz/set.c
new file mode 100644
index 0000000..d94ab74
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set.c
@@ -0,0 +1,48 @@
+/* mpz_set (dest_integer, src_integer) -- Assign DEST_INTEGER from SRC_INTEGER.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set (mpz_ptr w, mpz_srcptr u)
+#else
+mpz_set (w, u)
+ mpz_ptr w;
+ mpz_srcptr u;
+#endif
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+
+ usize = u->_mp_size;
+ size = ABS (usize);
+
+ if (w->_mp_alloc < size)
+ _mpz_realloc (w, size);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ MPN_COPY (wp, up, size);
+ w->_mp_size = usize;
+}
diff --git a/gnu/lib/libgmp/mpz/set_d.c b/gnu/lib/libgmp/mpz/set_d.c
new file mode 100644
index 0000000..c09b1d9
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_d.c
@@ -0,0 +1,93 @@
+/* mpz_set_d(integer, val) -- Assign INTEGER with a double value VAL.
+
+Copyright (C) 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set_d (mpz_ptr r, double d)
+#else
+mpz_set_d (r, d)
+ mpz_ptr r;
+ double d;
+#endif
+{
+ int negative;
+ mp_size_t size;
+ mp_limb_t tp[3];
+ mp_ptr rp;
+
+ negative = d < 0;
+ d = ABS (d);
+
+ /* Handle small arguments quickly. */
+ if (d < MP_BASE_AS_DOUBLE)
+ {
+ mp_limb_t tmp;
+ tmp = d;
+ PTR(r)[0] = tmp;
+ SIZ(r) = negative ? -(tmp != 0) : (tmp != 0);
+ return;
+ }
+
+ size = __gmp_extract_double (tp, d);
+
+ if (ALLOC(r) < size)
+ _mpz_realloc (r, size);
+
+ rp = PTR (r);
+
+#if BITS_PER_MP_LIMB == 32
+ switch (size)
+ {
+ default:
+ MPN_ZERO (rp, size - 3);
+ rp += size - 3;
+ case 3:
+ rp[2] = tp[2];
+ rp[1] = tp[1];
+ rp[0] = tp[0];
+ break;
+ case 2:
+ rp[1] = tp[2];
+ rp[0] = tp[1];
+ break;
+ case 1:
+ abort ();
+ }
+#else
+ switch (size)
+ {
+ default:
+ MPN_ZERO (rp, size - 2);
+ rp += size - 2;
+ case 2:
+ rp[1] = tp[1];
+ rp[0] = tp[0];
+ break;
+ case 1:
+ abort ();
+ }
+#endif
+
+ SIZ(r) = negative ? -size : size;
+}
diff --git a/gnu/lib/libgmp/mpz/set_f.c b/gnu/lib/libgmp/mpz/set_f.c
new file mode 100644
index 0000000..9547907
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_f.c
@@ -0,0 +1,64 @@
+/* mpz_set_f (dest_integer, src_float) -- Assign DEST_INTEGER from SRC_FLOAT.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set_f (mpz_ptr w, mpf_srcptr u)
+#else
+mpz_set_f (w, u)
+ mpz_ptr w;
+ mpf_srcptr u;
+#endif
+{
+ mp_ptr wp, up;
+ mp_size_t usize, size;
+ mp_exp_t exp;
+
+ usize = SIZ (u);
+ size = ABS (usize);
+ exp = EXP (u);
+
+ if (w->_mp_alloc < exp)
+ _mpz_realloc (w, exp);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ if (exp <= 0)
+ {
+ SIZ (w) = 0;
+ return;
+ }
+ if (exp < size)
+ {
+ MPN_COPY (wp, up + size - exp, exp);
+ }
+ else
+ {
+ MPN_ZERO (wp, exp - size);
+ MPN_COPY (wp + exp - size, up, size);
+ }
+
+ w->_mp_size = usize >= 0 ? exp : -exp;
+}
diff --git a/gnu/lib/libgmp/mpz/set_q.c b/gnu/lib/libgmp/mpz/set_q.c
new file mode 100644
index 0000000..61bd5c7
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_q.c
@@ -0,0 +1,36 @@
+/* mpz_set_q (dest_integer, src_rational) -- Assign DEST_INTEGER from
+ SRC_rational.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set_q (mpz_ptr w, mpq_srcptr u)
+#else
+mpz_set_q (w, u)
+ mpz_ptr w;
+ mpq_srcptr u;
+#endif
+{
+ mpz_tdiv_q (w, mpq_numref (u), mpq_denref (u));
+}
diff --git a/gnu/lib/libgmp/mpz/set_si.c b/gnu/lib/libgmp/mpz/set_si.c
new file mode 100644
index 0000000..82a90a3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_si.c
@@ -0,0 +1,48 @@
+/* mpz_set_si(integer, val) -- Assign INTEGER with a small value VAL.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set_si (mpz_ptr dest, signed long int val)
+#else
+mpz_set_si (dest, val)
+ mpz_ptr dest;
+ signed long int val;
+#endif
+{
+ /* We don't check if the allocation is enough, since the rest of the
+ package ensures it's at least 1, which is what we need here. */
+ if (val > 0)
+ {
+ dest->_mp_d[0] = val;
+ dest->_mp_size = 1;
+ }
+ else if (val < 0)
+ {
+ dest->_mp_d[0] = -val;
+ dest->_mp_size = -1;
+ }
+ else
+ dest->_mp_size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz/set_str.c b/gnu/lib/libgmp/mpz/set_str.c
new file mode 100644
index 0000000..d1334b1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_str.c
@@ -0,0 +1,132 @@
+/* mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated
+ string STRING in base BASE to multiple precision integer in
+ MP_DEST. Allow white space in the string. If BASE == 0 determine
+ the base in the C standard way, i.e. 0xhh...h means base 16,
+ 0oo...o means base 8, otherwise assume base 10.
+
+Copyright (C) 1991, 1993, 1994, Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+static int
+digit_value_in_base (c, base)
+ int c;
+ int base;
+{
+ int digit;
+
+ if (isdigit (c))
+ digit = c - '0';
+ else if (islower (c))
+ digit = c - 'a' + 10;
+ else if (isupper (c))
+ digit = c - 'A' + 10;
+ else
+ return -1;
+
+ if (digit < base)
+ return digit;
+ return -1;
+}
+
+int
+#if __STDC__
+mpz_set_str (mpz_ptr x, const char *str, int base)
+#else
+mpz_set_str (x, str, base)
+ mpz_ptr x;
+ const char *str;
+ int base;
+#endif
+{
+ size_t str_size;
+ char *s, *begs;
+ size_t i;
+ mp_size_t xsize;
+ int c;
+ int negative;
+ TMP_DECL (marker);
+
+ /* Skip whitespace. */
+ do
+ c = *str++;
+ while (isspace (c));
+
+ negative = 0;
+ if (c == '-')
+ {
+ negative = 1;
+ c = *str++;
+ }
+
+ if (digit_value_in_base (c, base == 0 ? 10 : base) < 0)
+ return -1; /* error if no digits */
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+ if (c == '0')
+ {
+ base = 8;
+ c = *str++;
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ c = *str++;
+ }
+ }
+ }
+
+ TMP_MARK (marker);
+ str_size = strlen (str - 1);
+ s = begs = (char *) TMP_ALLOC (str_size + 1);
+
+ for (i = 0; i < str_size; i++)
+ {
+ if (!isspace (c))
+ {
+ int dig = digit_value_in_base (c, base);
+ if (dig < 0)
+ {
+ TMP_FREE (marker);
+ return -1;
+ }
+ *s++ = dig;
+ }
+ c = *str++;
+ }
+
+ str_size = s - begs;
+
+ xsize = str_size / __mp_bases[base].chars_per_limb + 1;
+ if (x->_mp_alloc < xsize)
+ _mpz_realloc (x, xsize);
+
+ xsize = mpn_set_str (x->_mp_d, (unsigned char *) begs, str_size, base);
+ x->_mp_size = negative ? -xsize : xsize;
+
+ TMP_FREE (marker);
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpz/set_ui.c b/gnu/lib/libgmp/mpz/set_ui.c
new file mode 100644
index 0000000..73f6cf5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/set_ui.c
@@ -0,0 +1,43 @@
+/* mpz_set_ui(integer, val) -- Assign INTEGER with a small value VAL.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_set_ui (mpz_ptr dest, unsigned long int val)
+#else
+mpz_set_ui (dest, val)
+ mpz_ptr dest;
+ unsigned long int val;
+#endif
+{
+ /* We don't check if the allocation is enough, since the rest of the
+ package ensures it's at least 1, which is what we need here. */
+ if (val > 0)
+ {
+ dest->_mp_d[0] = val;
+ dest->_mp_size = 1;
+ }
+ else
+ dest->_mp_size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz/setbit.c b/gnu/lib/libgmp/mpz/setbit.c
new file mode 100644
index 0000000..af59e2c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/setbit.c
@@ -0,0 +1,113 @@
+/* mpz_setbit -- set a specified bit.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_setbit (mpz_ptr d, unsigned long int bit_index)
+#else
+mpz_setbit (d, bit_index)
+ mpz_ptr d;
+ unsigned long int bit_index;
+#endif
+{
+ mp_size_t dsize = d->_mp_size;
+ mp_ptr dp = d->_mp_d;
+ mp_size_t limb_index;
+
+ limb_index = bit_index / BITS_PER_MP_LIMB;
+ if (dsize >= 0)
+ {
+ if (limb_index < dsize)
+ {
+ dp[limb_index] |= (mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB);
+ d->_mp_size = dsize;
+ }
+ else
+ {
+ /* Ugh. The bit should be set outside of the end of the
+ number. We have to increase the size of the number. */
+ if (d->_mp_alloc < limb_index + 1)
+ {
+ _mpz_realloc (d, limb_index + 1);
+ dp = d->_mp_d;
+ }
+ MPN_ZERO (dp + dsize, limb_index - dsize);
+ dp[limb_index] = (mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB);
+ d->_mp_size = limb_index + 1;
+ }
+ }
+ else
+ {
+ mp_size_t zero_bound;
+
+ /* Simulate two's complement arithmetic, i.e. simulate
+ 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
+ 2. set the bit.
+ 3. Set OP = ~OP + 1. */
+
+ dsize = -dsize;
+
+ /* No upper bound on this loop, we're sure there's a non-zero limb
+ sooner ot later. */
+ for (zero_bound = 0; ; zero_bound++)
+ if (dp[zero_bound] != 0)
+ break;
+
+ if (limb_index > zero_bound)
+ {
+ if (limb_index < dsize)
+ dp[limb_index] &= ~((mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB));
+ else
+ ;
+ }
+ else if (limb_index == zero_bound)
+ {
+ dp[limb_index] = ((dp[limb_index] - 1)
+ & ~((mp_limb_t) 1 << (bit_index % BITS_PER_MP_LIMB))) + 1;
+ if (dp[limb_index] == 0)
+ {
+ mp_size_t i;
+ for (i = limb_index + 1; i < dsize; i++)
+ {
+ dp[i] += 1;
+ if (dp[i] != 0)
+ goto fin;
+ }
+ /* We got carry all way out beyond the end of D. Increase
+ its size (and allocation if necessary). */
+ dsize++;
+ if (d->_mp_alloc < dsize)
+ {
+ _mpz_realloc (d, dsize);
+ dp = d->_mp_d;
+ }
+ dp[i] = 1;
+ d->_mp_size = -dsize;
+ fin:;
+ }
+ }
+ else
+ ;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/size.c b/gnu/lib/libgmp/mpz/size.c
new file mode 100644
index 0000000..0b09fbe
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/size.c
@@ -0,0 +1,35 @@
+/* mpz_size(x) -- return the number of lims currently used by the
+ value of integer X.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#if __STDC__
+mpz_size (mpz_srcptr x)
+#else
+mpz_size (x)
+ mpz_srcptr x;
+#endif
+{
+ return ABS (x->_mp_size);
+}
diff --git a/gnu/lib/libgmp/mpz/sizeinbase.c b/gnu/lib/libgmp/mpz/sizeinbase.c
new file mode 100644
index 0000000..51bd555
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/sizeinbase.c
@@ -0,0 +1,60 @@
+/* mpz_sizeinbase(x, base) -- return an approximation to the number of
+ character the integer X would have printed in base BASE. The
+ approximation is never too small.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+size_t
+#if __STDC__
+mpz_sizeinbase (mpz_srcptr x, int base)
+#else
+mpz_sizeinbase (x, base)
+ mpz_srcptr x;
+ int base;
+#endif
+{
+ mp_size_t size = ABS (x->_mp_size);
+ int lb_base, cnt;
+ size_t totbits;
+
+ /* Special case for X == 0. */
+ if (size == 0)
+ return 1;
+
+ /* Calculate the total number of significant bits of X. */
+ count_leading_zeros (cnt, x->_mp_d[size - 1]);
+ totbits = size * BITS_PER_MP_LIMB - cnt;
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* Special case for powers of 2, giving exact result. */
+
+ count_leading_zeros (lb_base, base);
+ lb_base = BITS_PER_MP_LIMB - lb_base - 1;
+
+ return (totbits + lb_base - 1) / lb_base;
+ }
+ else
+ return (size_t) (totbits * __mp_bases[base].chars_per_bit_exactly) + 1;
+}
diff --git a/gnu/lib/libgmp/mpz/sqrt.c b/gnu/lib/libgmp/mpz/sqrt.c
new file mode 100644
index 0000000..44c554e
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/sqrt.c
@@ -0,0 +1,85 @@
+/* mpz_sqrt(root, u) -- Set ROOT to floor(sqrt(U)).
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_sqrt (mpz_ptr root, mpz_srcptr op)
+#else
+mpz_sqrt (root, op)
+ mpz_ptr root;
+ mpz_srcptr op;
+#endif
+{
+ mp_size_t op_size, root_size;
+ mp_ptr root_ptr, op_ptr;
+ mp_ptr free_me = NULL;
+ mp_size_t free_me_size;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ op_size = op->_mp_size;
+ if (op_size < 0)
+ op_size = 1 / (op_size > 0); /* Divide by zero for negative OP. */
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+
+ root_ptr = root->_mp_d;
+ op_ptr = op->_mp_d;
+
+ if (root->_mp_alloc < root_size)
+ {
+ if (root_ptr == op_ptr)
+ {
+ free_me = root_ptr;
+ free_me_size = root->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (root_ptr, root->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ root->_mp_alloc = root_size;
+ root_ptr = (mp_ptr) (*_mp_allocate_func) (root_size * BYTES_PER_MP_LIMB);
+ root->_mp_d = root_ptr;
+ }
+ else
+ {
+ /* Make OP not overlap with ROOT. */
+ if (root_ptr == op_ptr)
+ {
+ /* ROOT and OP are identical. Allocate temporary space for OP. */
+ op_ptr = (mp_ptr) TMP_ALLOC (op_size * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. Hack: Avoid temporary variable
+ by using ROOT_PTR. */
+ MPN_COPY (op_ptr, root_ptr, op_size);
+ }
+ }
+
+ mpn_sqrtrem (root_ptr, NULL, op_ptr, op_size);
+
+ root->_mp_size = root_size;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/sqrtrem.c b/gnu/lib/libgmp/mpz/sqrtrem.c
new file mode 100644
index 0000000..757cc5d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/sqrtrem.c
@@ -0,0 +1,107 @@
+/* mpz_sqrtrem(root,rem,x) -- Set ROOT to floor(sqrt(X)) and REM
+ to the remainder, i.e. X - ROOT**2.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_sqrtrem (mpz_ptr root, mpz_ptr rem, mpz_srcptr op)
+#else
+mpz_sqrtrem (root, rem, op)
+ mpz_ptr root;
+ mpz_ptr rem;
+ mpz_srcptr op;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+msqrt (mpz_srcptr op, mpz_ptr root, mpz_ptr rem)
+#else
+msqrt (op, root, rem)
+ mpz_srcptr op;
+ mpz_ptr root;
+ mpz_ptr rem;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size_t op_size, root_size, rem_size;
+ mp_ptr root_ptr, op_ptr;
+ mp_ptr free_me = NULL;
+ mp_size_t free_me_size;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ op_size = op->_mp_size;
+ if (op_size < 0)
+ op_size = 1 / (op_size > 0); /* Divide by zero for negative OP. */
+
+ if (rem->_mp_alloc < op_size)
+ _mpz_realloc (rem, op_size);
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+
+ root_ptr = root->_mp_d;
+ op_ptr = op->_mp_d;
+
+ if (root->_mp_alloc < root_size)
+ {
+ if (root_ptr == op_ptr)
+ {
+ free_me = root_ptr;
+ free_me_size = root->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (root_ptr, root->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ root->_mp_alloc = root_size;
+ root_ptr = (mp_ptr) (*_mp_allocate_func) (root_size * BYTES_PER_MP_LIMB);
+ root->_mp_d = root_ptr;
+ }
+ else
+ {
+ /* Make OP not overlap with ROOT. */
+ if (root_ptr == op_ptr)
+ {
+ /* ROOT and OP are identical. Allocate temporary space for OP. */
+ op_ptr = (mp_ptr) TMP_ALLOC (op_size * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. Hack: Avoid temporary variable
+ by using ROOT_PTR. */
+ MPN_COPY (op_ptr, root_ptr, op_size);
+ }
+ }
+
+ rem_size = mpn_sqrtrem (root_ptr, rem->_mp_d, op_ptr, op_size);
+
+ root->_mp_size = root_size;
+
+ /* Write remainder size last, to enable us to define this function to
+ give only the square root remainder, if the user calls if with
+ ROOT == REM. */
+ rem->_mp_size = rem_size;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/sub.c b/gnu/lib/libgmp/mpz/sub.c
new file mode 100644
index 0000000..56ef1a1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/sub.c
@@ -0,0 +1,120 @@
+/* mpz_sub -- Subtract two integers.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#if __STDC__
+mpz_sub (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
+#else
+mpz_sub (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ mpz_srcptr v;
+#endif
+#else /* BERKELEY_MP */
+void
+#if __STDC__
+msub (mpz_srcptr u, mpz_srcptr v, mpz_ptr w)
+#else
+msub (u, v, w)
+ mpz_srcptr u;
+ mpz_srcptr v;
+ mpz_ptr w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_srcptr up, vp;
+ mp_ptr wp;
+ mp_size_t usize, vsize, wsize;
+ mp_size_t abs_usize;
+ mp_size_t abs_vsize;
+
+ usize = u->_mp_size;
+ vsize = -v->_mp_size; /* The "-" makes the difference from mpz_add */
+ abs_usize = ABS (usize);
+ abs_vsize = ABS (vsize);
+
+ if (abs_usize < abs_vsize)
+ {
+ /* Swap U and V. */
+ {const __mpz_struct *t = u; u = v; v = t;}
+ {mp_size_t t = usize; usize = vsize; vsize = t;}
+ {mp_size_t t = abs_usize; abs_usize = abs_vsize; abs_vsize = t;}
+ }
+
+ /* True: ABS_USIZE >= ABS_VSIZE. */
+
+ /* If not space for w (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ wp = w->_mp_d;
+
+ if ((usize ^ vsize) < 0)
+ {
+ /* U and V have different sign. Need to compare them to determine
+ which operand to subtract from which. */
+
+ /* This test is right since ABS_USIZE >= ABS_VSIZE. */
+ if (abs_usize != abs_vsize)
+ {
+ mpn_sub (wp, up, abs_usize, vp, abs_vsize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ else if (mpn_cmp (up, vp, abs_usize) < 0)
+ {
+ mpn_sub_n (wp, vp, up, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize >= 0)
+ wsize = -wsize;
+ }
+ else
+ {
+ mpn_sub_n (wp, up, vp, abs_usize);
+ wsize = abs_usize;
+ MPN_NORMALIZE (wp, wsize);
+ if (usize < 0)
+ wsize = -wsize;
+ }
+ }
+ else
+ {
+ /* U and V have same sign. Add them. */
+ mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
+ wp[abs_usize] = cy_limb;
+ wsize = abs_usize + cy_limb;
+ if (usize < 0)
+ wsize = -wsize;
+ }
+
+ w->_mp_size = wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/sub_ui.c b/gnu/lib/libgmp/mpz/sub_ui.c
new file mode 100644
index 0000000..7dea4b6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/sub_ui.c
@@ -0,0 +1,84 @@
+/* mpz_sub_ui -- Subtract an unsigned one-word integer from an MP_INT.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_sub_ui (mpz_ptr w, mpz_srcptr u, unsigned long int v)
+#else
+mpz_sub_ui (w, u, v)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int v;
+#endif
+{
+ mp_srcptr up;
+ mp_ptr wp;
+ mp_size_t usize, wsize;
+ mp_size_t abs_usize;
+
+ usize = u->_mp_size;
+ abs_usize = ABS (usize);
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->_mp_d;
+ wp = w->_mp_d;
+
+ if (abs_usize == 0)
+ {
+ wp[0] = v;
+ w->_mp_size = -(v != 0);
+ return;
+ }
+
+ if (usize < 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_add_1 (wp, up, abs_usize, v);
+ wp[abs_usize] = cy;
+ wsize = -(abs_usize + cy);
+ }
+ else
+ {
+ /* The signs are different. Need exact comparison to determine
+ which operand to subtract from which. */
+ if (abs_usize == 1 && up[0] < v)
+ {
+ wp[0] = v - up[0];
+ wsize = -1;
+ }
+ else
+ {
+ mpn_sub_1 (wp, up, abs_usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = abs_usize - (wp[abs_usize - 1] == 0);
+ }
+ }
+
+ w->_mp_size = wsize;
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_q.c b/gnu/lib/libgmp/mpz/tdiv_q.c
new file mode 100644
index 0000000..b4d3636
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_q.c
@@ -0,0 +1,133 @@
+/* mpz_tdiv_q -- divide two integers and produce a quotient.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_tdiv_q (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
+#else
+mpz_tdiv_q (quot, num, den)
+ mpz_ptr quot;
+ mpz_srcptr num;
+ mpz_srcptr den;
+#endif
+{
+ mp_srcptr np, dp;
+ mp_ptr qp, rp;
+ mp_size_t nsize = num->_mp_size;
+ mp_size_t dsize = den->_mp_size;
+ mp_size_t qsize, rsize;
+ mp_size_t sign_quotient = nsize ^ dsize;
+ unsigned normalization_steps;
+ mp_limb_t q_limb;
+ TMP_DECL (marker);
+
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+
+ /* Ensure space is enough for quotient. */
+
+ qsize = nsize - dsize + 1; /* qsize cannot be bigger than this. */
+ if (qsize <= 0)
+ {
+ quot->_mp_size = 0;
+ return;
+ }
+
+ if (quot->_mp_alloc < qsize)
+ _mpz_realloc (quot, qsize);
+
+ qp = quot->_mp_d;
+ np = num->_mp_d;
+ dp = den->_mp_d;
+
+ /* Optimize division by a single-limb divisor. */
+ if (dsize == 1)
+ {
+ mpn_divmod_1 (qp, np, nsize, dp[0]);
+ qsize -= qp[qsize - 1] == 0;
+ quot->_mp_size = sign_quotient >= 0 ? qsize : -qsize;
+ return;
+ }
+
+ TMP_MARK (marker);
+
+ rp = (mp_ptr) TMP_ALLOC ((nsize + 1) * BYTES_PER_MP_LIMB);
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant word. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ significant word. Move the shifted numerator in the remainder
+ meanwhile. */
+ nlimb = mpn_lshift (rp, np, nsize, normalization_steps);
+ if (nlimb != 0)
+ {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else
+ {
+ /* The denominator is already normalized, as required. Copy it to
+ temporary space if it overlaps with the quotient. */
+ if (dp == qp)
+ {
+ dp = (mp_ptr) TMP_ALLOC (dsize * BYTES_PER_MP_LIMB);
+ MPN_COPY ((mp_ptr) dp, qp, dsize);
+ }
+
+ /* Move the numerator to the remainder. */
+ MPN_COPY (rp, np, nsize);
+ rsize = nsize;
+ }
+
+ q_limb = mpn_divmod (qp, rp, rsize, dp, dsize);
+
+ qsize = rsize - dsize;
+ if (q_limb)
+ {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->_mp_size = sign_quotient >= 0 ? qsize : -qsize;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_q_2exp.c b/gnu/lib/libgmp/mpz/tdiv_q_2exp.c
new file mode 100644
index 0000000..e70d810
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_q_2exp.c
@@ -0,0 +1,68 @@
+/* mpz_tdiv_q_2exp -- Divide an integer by 2**CNT. Round the quotient
+ towards -infinity.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_tdiv_q_2exp (mpz_ptr w, mpz_srcptr u, unsigned long int cnt)
+#else
+mpz_tdiv_q_2exp (w, u, cnt)
+ mpz_ptr w;
+ mpz_srcptr u;
+ unsigned long int cnt;
+#endif
+{
+ mp_size_t usize, wsize;
+ mp_size_t limb_cnt;
+
+ usize = u->_mp_size;
+ limb_cnt = cnt / BITS_PER_MP_LIMB;
+ wsize = ABS (usize) - limb_cnt;
+ if (wsize <= 0)
+ w->_mp_size = 0;
+ else
+ {
+ mp_ptr wp;
+ mp_srcptr up;
+
+ if (w->_mp_alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ wp = w->_mp_d;
+ up = u->_mp_d;
+
+ cnt %= BITS_PER_MP_LIMB;
+ if (cnt != 0)
+ {
+ mpn_rshift (wp, up + limb_cnt, wsize, cnt);
+ wsize -= wp[wsize - 1] == 0;
+ }
+ else
+ {
+ MPN_COPY_INCR (wp, up + limb_cnt, wsize);
+ }
+
+ w->_mp_size = usize >= 0 ? wsize : -wsize;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_q_ui.c b/gnu/lib/libgmp/mpz/tdiv_q_ui.c
new file mode 100644
index 0000000..9048e0a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_q_ui.c
@@ -0,0 +1,63 @@
+/* mpz_tdiv_q_ui(quot, dividend, divisor_limb)
+ -- Divide DIVIDEND by DIVISOR_LIMB and store the result in QUOT.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_tdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_tdiv_q_ui (quot, dividend, divisor)
+ mpz_ptr quot;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (size == 0)
+ {
+ quot->_mp_size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ mpn_divmod_1 (quot_ptr, dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ /* The quotient is SIZE limbs, but the most significant might be zero. */
+ size -= quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_qr.c b/gnu/lib/libgmp/mpz/tdiv_qr.c
new file mode 100644
index 0000000..500e199
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_qr.c
@@ -0,0 +1,39 @@
+/* mpz_tdiv_qr(quot,rem,dividend,divisor) -- Set QUOT to DIVIDEND/DIVISOR,
+ and REM to DIVIDEND mod DIVISOR.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_tdiv_qr (mpz_ptr quot, mpz_ptr rem, mpz_srcptr num, mpz_srcptr den)
+#else
+mpz_tdiv_qr (quot, rem, num, den)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr num;
+ mpz_srcptr den;
+#endif
+
+#define COMPUTE_QUOTIENT
+#include "dmincl.c"
diff --git a/gnu/lib/libgmp/mpz/tdiv_qr_ui.c b/gnu/lib/libgmp/mpz/tdiv_qr_ui.c
new file mode 100644
index 0000000..cb5041c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_qr_ui.c
@@ -0,0 +1,78 @@
+/* mpz_tdiv_qr_ui(quot,rem,dividend,short_divisor) --
+ Set QUOT to DIVIDEND / SHORT_DIVISOR
+ and REM to DIVIDEND mod SHORT_DIVISOR.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_tdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_tdiv_qr_ui (quot, rem, dividend, divisor)
+ mpz_ptr quot;
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_ptr quot_ptr;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (size == 0)
+ {
+ quot->_mp_size = 0;
+ rem->_mp_size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->_mp_alloc < size)
+ _mpz_realloc (quot, size);
+
+ quot_ptr = quot->_mp_d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr, dividend->_mp_d, size,
+ (mp_limb_t) divisor);
+
+ if (remainder_limb == 0)
+ rem->_mp_size = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ rem->_mp_size = dividend_size >= 0 ? 1 : -1;
+ rem->_mp_d[0] = remainder_limb;
+ }
+
+ /* The quotient is SIZE limbs, but the most significant might be zero. */
+ size -= quot_ptr[size - 1] == 0;
+ quot->_mp_size = dividend_size >= 0 ? size : -size;
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_r.c b/gnu/lib/libgmp/mpz/tdiv_r.c
new file mode 100644
index 0000000..813a0d4
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_r.c
@@ -0,0 +1,37 @@
+/* mpz_tdiv_r(rem, dividend, divisor) -- Set REM to DIVIDEND mod DIVISOR.
+
+Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_tdiv_r (mpz_ptr rem, mpz_srcptr num, mpz_srcptr den)
+#else
+mpz_tdiv_r (rem, num, den)
+ mpz_ptr rem;
+ mpz_srcptr num;
+ mpz_srcptr den;
+#endif
+
+#undef COMPUTE_QUOTIENT
+#include "dmincl.c"
diff --git a/gnu/lib/libgmp/mpz/tdiv_r_2exp.c b/gnu/lib/libgmp/mpz/tdiv_r_2exp.c
new file mode 100644
index 0000000..99d617e
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_r_2exp.c
@@ -0,0 +1,79 @@
+/* mpz_tdiv_r_2exp -- Divide a integer by 2**CNT and produce a remainder.
+
+Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, unsigned long int cnt)
+#else
+mpz_tdiv_r_2exp (res, in, cnt)
+ mpz_ptr res;
+ mpz_srcptr in;
+ unsigned long int cnt;
+#endif
+{
+ mp_size_t in_size = ABS (in->_mp_size);
+ mp_size_t res_size;
+ mp_size_t limb_cnt = cnt / BITS_PER_MP_LIMB;
+ mp_srcptr in_ptr = in->_mp_d;
+
+ if (in_size > limb_cnt)
+ {
+ /* The input operand is (probably) greater than 2**CNT. */
+ mp_limb_t x;
+
+ x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % BITS_PER_MP_LIMB) - 1);
+ if (x != 0)
+ {
+ res_size = limb_cnt + 1;
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ res->_mp_d[limb_cnt] = x;
+ }
+ else
+ {
+ res_size = limb_cnt;
+ MPN_NORMALIZE (in_ptr, res_size);
+
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+ }
+ else
+ {
+ /* The input operand is smaller than 2**CNT. We perform a no-op,
+ apart from that we might need to copy IN to RES. */
+ res_size = in_size;
+ if (res->_mp_alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+
+ if (res != in)
+ MPN_COPY (res->_mp_d, in->_mp_d, limb_cnt);
+ res->_mp_size = in->_mp_size >= 0 ? res_size : -res_size;
+}
diff --git a/gnu/lib/libgmp/mpz/tdiv_r_ui.c b/gnu/lib/libgmp/mpz/tdiv_r_ui.c
new file mode 100644
index 0000000..0428b52
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tdiv_r_ui.c
@@ -0,0 +1,64 @@
+/* mpz_tdiv_r_ui(rem, dividend, divisor_limb)
+ -- Set REM to DIVDEND mod DIVISOR_LIMB.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#if __STDC__
+mpz_tdiv_r_ui (mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
+#else
+mpz_tdiv_r_ui (rem, dividend, divisor)
+ mpz_ptr rem;
+ mpz_srcptr dividend;
+ unsigned long int divisor;
+#endif
+{
+ mp_size_t dividend_size;
+ mp_size_t size;
+ mp_limb_t remainder_limb;
+
+ dividend_size = dividend->_mp_size;
+ size = ABS (dividend_size);
+
+ if (size == 0)
+ {
+ rem->_mp_size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ remainder_limb = mpn_mod_1 (dividend->_mp_d, size, (mp_limb_t) divisor);
+
+ if (remainder_limb == 0)
+ rem->_mp_size = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ rem->_mp_size = dividend_size >= 0 ? 1 : -1;
+ rem->_mp_d[0] = remainder_limb;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz/tests/Makefile.in b/gnu/lib/libgmp/mpz/tests/Makefile.in
new file mode 100644
index 0000000..5a0cf59
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/Makefile.in
@@ -0,0 +1,126 @@
+# Makefile for mpz/tests for GNU MP
+
+srcdir = .
+
+CC = gcc
+
+TEST_LIBS = ../../libgmp.a
+INCLUDES = -I../../mpn -I$(srcdir)/../..
+CFLAGS = -g -O
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+TEST_SRCS = t-mul.c t-tdiv.c t-tdiv_ui.c t-fdiv.c t-fdiv_ui.c t-gcd.c \
+ t-gcd2.c dive.c t-sqrtrem.c convert.c io.c logic.c t-powm.c t-powm_ui.c \
+ reuse.c
+TEST_OBJS = t-mul.o t-tdiv.o t-tdiv_ui.o t-fdiv.o t-fdiv_ui.o t-gcd.o \
+ t-gcd2.o dive.o t-sqrtrem.o convert.o io.o logic.o t-powm.o t-powm_ui.o \
+ reuse.o
+TESTS = t-mul t-tdiv t-tdiv_ui t-fdiv t-fdiv_ui t-gcd t-gcd2 \
+ dive t-sqrtrem convert io logic t-powm t-powm_ui reuse
+
+check: Makefile st-mul st-tdiv st-tdiv_ui st-fdiv st-fdiv_ui st-gcd st-gcd2 st-dive \
+ st-sqrtrem st-convert st-io st-logic st-powm st-powm_ui st-reuse
+ @echo "The tests passed."
+
+st-mul: t-mul
+ ./t-mul
+ touch $@
+st-tdiv: t-tdiv
+ ./t-tdiv
+ touch $@
+st-tdiv_ui: t-tdiv_ui
+ ./t-tdiv_ui
+ touch $@
+st-fdiv: t-fdiv
+ ./t-fdiv
+ touch $@
+st-fdiv_ui: t-fdiv_ui
+ ./t-fdiv_ui
+ touch $@
+st-gcd: t-gcd
+ ./t-gcd
+ touch $@
+st-gcd2: t-gcd2
+ ./t-gcd2
+ touch $@
+st-dive: dive
+ ./dive
+ touch $@
+st-sqrtrem: t-sqrtrem
+ ./t-sqrtrem
+ touch $@
+st-convert: convert
+ ./convert
+ touch $@
+st-io: io
+ ./io
+ touch $@
+st-logic: logic
+ ./logic
+ touch $@
+st-powm: t-powm
+ ./t-powm
+ touch $@
+st-powm_ui: t-powm_ui
+ ./t-powm_ui
+ touch $@
+st-reuse: reuse
+ ./reuse
+ touch $@
+
+t-mul: t-mul.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-tdiv: t-tdiv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-tdiv_ui: t-tdiv_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-fdiv: t-fdiv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-fdiv_ui: t-fdiv_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-gcd: t-gcd.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-gcd2: t-gcd2.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+dive: dive.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-sqrtrem: t-sqrtrem.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+convert: convert.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+io: io.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+logic: logic.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-powm: t-powm.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-powm_ui: t-powm_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+reuse: reuse.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+
+t-mul.o: $(srcdir)/t-mul.c
+t-tdiv.o: $(srcdir)/t-tdiv.c
+t-tdiv_ui.o: $(srcdir)/t-tdiv_ui.c
+t-fdiv.o: $(srcdir)/t-fdiv.c
+t-fdiv_ui.o: $(srcdir)/t-fdiv_ui.c
+t-gcd.o: $(srcdir)/t-gcd.c
+t-gcd2.o: $(srcdir)/t-gcd2.c
+dive.o: $(srcdir)/dive.c
+t-sqrtrem.o: $(srcdir)/t-sqrtrem.c
+convert.o: $(srcdir)/convert.c
+io.o: $(srcdir)/io.c
+logic.o: $(srcdir)/logic.c
+t-powm.o: $(srcdir)/t-powm.c
+t-powm_ui.o: $(srcdir)/t-powm_ui.c
+reuse.o: $(srcdir)/reuse.c
+
+clean mostlyclean:
+ rm -f *.o st-* $(TESTS)
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
diff --git a/gnu/lib/libgmp/mpz/tests/configure.in b/gnu/lib/libgmp/mpz/tests/configure.in
new file mode 100644
index 0000000..dacc177
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/configure.in
@@ -0,0 +1,11 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory. For more information, check any
+# existing configure script.
+
+srctrigger=t-mul.c
+srcname="gmp/mpz/tests"
+
+# per-host:
+
+# per-target:
diff --git a/gnu/lib/libgmp/mpz/tests/convert.c b/gnu/lib/libgmp/mpz/tests/convert.c
new file mode 100644
index 0000000..1d82370
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/convert.c
@@ -0,0 +1,80 @@
+/* Test conversion using mpz_get_str and mpz_set_str.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 32
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 100000;
+ char *str;
+ int base;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&op1, size);
+ base = urandom () % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ str = mpz_get_str ((char *) 0, base, &op1);
+ mpz_set_str (&op2, str, base);
+ free (str);
+
+ if (mpz_cmp (&op1, &op2))
+ {
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (&op1, -16);
+ fprintf (stderr, "base = %d\n", base);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/dive.c b/gnu/lib/libgmp/mpz/tests/dive.c
new file mode 100644
index 0000000..8d3516d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/dive.c
@@ -0,0 +1,87 @@
+/* Test mpz_mul, mpz_divexact.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 32
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2;
+ mpz_t prod, quot;
+ mp_size_t size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (prod);
+ mpz_init (quot);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (op1, size);
+
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (op2, size);
+ }
+ while (mpz_cmp_ui (op2, 0) == 0);
+
+ mpz_mul (prod, op1, op2);
+
+ mpz_divexact (quot, prod, op2);
+ if (mpz_cmp (quot, op1) != 0)
+ dump_abort (quot, op1);
+ }
+
+ exit (0);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "ref = "); debug_mp (op1, -16);
+ fprintf (stderr, "wrong = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/io-binary.c b/gnu/lib/libgmp/mpz/tests/io-binary.c
new file mode 100644
index 0000000..c28f2a5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/io-binary.c
@@ -0,0 +1,76 @@
+/* Test mpz_inp_binary and mpz_out_binary.
+
+ We write and read back some test strings, and both compare
+ the numerical result, and make sure the pattern on file is
+ what we expect. The latter is important for compatibility
+ between machines with different word sizes. */
+
+#include <stdio.h>
+#include "gmp.h"
+
+FILE *file;
+
+test (str, binary_len, binary_str)
+ char *str;
+ int binary_len;
+ char *binary_str;
+{
+ mpz_t x, y;
+ int n_written;
+ char buf[100];
+
+ mpz_init_set_str (x, str, 0);
+ mpz_init (y);
+
+ fseek (file, 0, SEEK_SET);
+ mpz_out_binary (file, x);
+ n_written = ftell (file);
+ if (n_written != binary_len)
+ abort ();
+
+ fseek (file, 0, SEEK_SET);
+ mpz_inp_binary (y, file);
+ if (n_written != ftell (file))
+ abort ();
+ if (mpz_cmp (x, y) != 0)
+ abort ();
+
+ fseek (file, 0, SEEK_SET);
+ fread (buf, n_written, 1, file);
+ if (memcmp (buf, binary_str, binary_len) != 0)
+ abort ();
+
+ mpz_clear (x);
+}
+
+main ()
+{
+ file = fopen ("xtmpfile", "w+");
+
+ test ("0", 4,
+ "\000\000\000\000");
+
+ test ("1", 5,
+ "\000\000\000\001\001");
+ test ("0x123", 6,
+ "\000\000\000\002\001\043");
+ test ("0xdeadbeef", 8,
+ "\000\000\000\004\336\255\276\357");
+ test ("0xbabefaced", 9,
+ "\000\000\000\005\013\253\357\254\355");
+ test ("0x123456789facade0", 12,
+ "\000\000\000\010\022\064\126\170\237\254\255\340");
+
+ test ("-1", 5,
+ "\377\377\377\377\001");
+ test ("-0x123", 6,
+ "\377\377\377\376\001\043");
+ test ("-0xdeadbeef", 8,
+ "\377\377\377\374\336\255\276\357");
+ test ("-0xbabefaced", 9,
+ "\377\377\377\373\013\253\357\254\355");
+ test ("-0x123456789facade0", 12,
+ "\377\377\377\370\022\064\126\170\237\254\255\340");
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/io.c b/gnu/lib/libgmp/mpz/tests/io.c
new file mode 100644
index 0000000..3dfa9a5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/io.c
@@ -0,0 +1,86 @@
+/* Test conversion and I/O using mpz_out_str and mpz_inp_str.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 10000;
+ FILE *fsin, *fsout;
+ int fd[2];
+ int base;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+
+ pipe (fd);
+ fsin = fdopen (fd[0], "r");
+ fsout = fdopen (fd[1], "w");
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&op1, size);
+ base = urandom () % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ mpz_out_str (fsout, base, &op1);
+ putc (' ', fsout);
+ fflush (fsout);
+ mpz_inp_str (&op2, fsin, base);
+
+ if (mpz_cmp (&op1, &op2))
+ {
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (&op1, -16);
+ fprintf (stderr, "base = %d\n", base);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/logic.c b/gnu/lib/libgmp/mpz/tests/logic.c
new file mode 100644
index 0000000..41a8cac
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/logic.c
@@ -0,0 +1,103 @@
+/* Test mpz_com, mpz_and, and mpz_ior.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t x, y, r1, r2;
+ mpz_t t1, t2, t3, t4;
+ mp_size_t xsize, ysize;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x);
+ mpz_init (y);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (t2);
+ mpz_init (t3);
+ mpz_init (t4);
+
+ for (i = 0; i < reps; i++)
+ {
+ xsize = urandom () % SIZE - SIZE/2;
+ mpz_random2 (x, xsize);
+
+ ysize = urandom () % SIZE - SIZE/2;
+ mpz_random2 (y, ysize);
+
+ mpz_com (r1, x);
+ mpz_com (r1, r1);
+ if (mpz_cmp (r1, x) != 0)
+ dump_abort ();
+
+ mpz_com (r1, y);
+ mpz_com (r2, r1);
+ if (mpz_cmp (r2, y) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ mpz_com (t2, y);
+ mpz_and (t3, t1, t2);
+ mpz_com (r1, t3);
+ mpz_ior (r2, x, y);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ mpz_com (t2, y);
+ mpz_ior (t3, t1, t2);
+ mpz_com (r1, t3);
+ mpz_and (r2, x, y);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort ()
+{
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/reuse.c b/gnu/lib/libgmp/mpz/tests/reuse.c
new file mode 100644
index 0000000..52fc5a5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/reuse.c
@@ -0,0 +1,135 @@
+/* Test that routines allow reusing a source variable as destination. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#if __STDC__
+typedef void (*dss_func) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+#else
+typedef void (*dss_func) ();
+#endif
+
+dss_func dss_funcs[] =
+{
+ mpz_add, mpz_and, mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r,
+ mpz_gcd, mpz_ior, mpz_mul, mpz_sub, mpz_tdiv_q, mpz_tdiv_r
+};
+
+char *dss_func_names[] =
+{
+ "mpz_add", "mpz_and", "mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r",
+ "mpz_gcd", "mpz_ior", "mpz_mul", "mpz_sub", "mpz_tdiv_q", "mpz_tdiv_r"
+};
+
+char dss_func_division[] = {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1};
+
+#if 0
+mpz_divexact /* requires special operands */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ int pass, reps = 10000;
+ mpz_t in1, in2, out1;
+ mpz_t res1, res2, res3;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (in1);
+ mpz_init (in2);
+ mpz_init (out1);
+ mpz_init (res1);
+ mpz_init (res2);
+ mpz_init (res3);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ mpz_random (in1, urandom () % SIZE - SIZE/2);
+ mpz_random (in2, urandom () % SIZE - SIZE/2);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ if (dss_func_division[i] && mpz_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dss_funcs[i]) (res1, in1, in2);
+
+ mpz_set (out1, in1);
+ (dss_funcs[i]) (out1, out1, in2);
+ mpz_set (res2, out1);
+
+ mpz_set (out1, in2);
+ (dss_funcs[i]) (out1, in1, out1);
+ mpz_set (res3, out1);
+
+ if (mpz_cmp (res1, res2) != 0)
+ dump_abort (dss_func_names[i], in1, in2);
+ if (mpz_cmp (res1, res3) != 0)
+ dump_abort (dss_func_names[i], in1, in2);
+ }
+ }
+
+ exit (0);
+}
+
+dump_abort (name, in1, in2)
+ char *name;
+ mpz_t in1, in2;
+{
+ printf ("failure in %s (", name);
+ mpz_out_str (stdout, -16, in1);
+ printf (" ");
+ mpz_out_str (stdout, -16, in2);
+ printf (")\n");
+ abort ();
+}
+
+#if 0
+void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_div_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mod_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+
+void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_com _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr));
+
+void mpz_tdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+
+void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr));
+
+void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_cdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_fdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_tdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr));
+
+unsigned long int mpz_cdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+
+unsigned long int mpz_cdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_cdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+#endif
diff --git a/gnu/lib/libgmp/mpz/tests/t-fdiv.c b/gnu/lib/libgmp/mpz/tests/t-fdiv.c
new file mode 100644
index 0000000..9de22d7
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-fdiv.c
@@ -0,0 +1,118 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr, mpz_fdiv_q,
+ mpz_fdiv_r, mpz_mul.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (divisor, divisor_size);
+ if (mpz_cmp_ui (divisor, 0) == 0)
+ continue;
+
+ mpz_fdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_fdiv_q (quotient2, dividend, divisor);
+ mpz_fdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (divisor, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend, divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c b/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c
new file mode 100644
index 0000000..74ba9fc
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr_ui, mpz_fdiv_q_ui,
+ mpz_fdiv_r_ui, mpz_mul, mpz_mul_ui.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ mp_limb_t divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_fdiv_qr_ui (quotient, remainder, dividend, divisor);
+ mpz_fdiv_q_ui (quotient2, dividend, divisor);
+ mpz_fdiv_r_ui (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) < 0)
+ dump_abort (dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend;
+ mp_limb_t divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-gcd.c b/gnu/lib/libgmp/mpz/tests/t-gcd.c
new file mode 100644
index 0000000..d9a7884
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-gcd.c
@@ -0,0 +1,132 @@
+/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp,
+ mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void mpz_refgcd (), debug_mp ();
+
+#ifndef SIZE
+#define SIZE 256 /* really needs to be this large to exercise corner cases! */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2;
+ mpz_t refgcd, gcd, s, t;
+ mpz_t temp1, temp2;
+ mp_size_t op1_size, op2_size;
+ int i;
+ int reps = 1000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (refgcd);
+ mpz_init (gcd);
+ mpz_init (temp1);
+ mpz_init (temp2);
+ mpz_init (s);
+ mpz_init (t);
+
+ for (i = 0; i < reps; i++)
+ {
+ op1_size = urandom () % SIZE - SIZE/2;
+ op2_size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (op1, op1_size);
+ mpz_random2 (op2, op2_size);
+
+ mpz_refgcd (refgcd, op1, op2);
+
+ mpz_gcd (gcd, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_gcdext (gcd, s, t, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_mul (temp1, s, op1);
+ mpz_mul (temp2, t, op2);
+ mpz_add (gcd, temp1, temp2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refgcd (g, x, y)
+ mpz_t g;
+ mpz_t x, y;
+{
+ mpz_t xx, yy;
+
+ mpz_init (xx);
+ mpz_init (yy);
+
+ mpz_abs (xx, x);
+ mpz_abs (yy, y);
+
+ for (;;)
+ {
+ if (mpz_cmp_ui (yy, 0) == 0)
+ {
+ mpz_set (g, xx);
+ break;
+ }
+ mpz_tdiv_r (xx, xx, yy);
+ if (mpz_cmp_ui (xx, 0) == 0)
+ {
+ mpz_set (g, yy);
+ break;
+ }
+ mpz_tdiv_r (yy, yy, xx);
+ }
+
+ mpz_clear (xx);
+ mpz_clear (yy);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-gcd2.c b/gnu/lib/libgmp/mpz/tests/t-gcd2.c
new file mode 100644
index 0000000..b7ad67c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-gcd2.c
@@ -0,0 +1,137 @@
+/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp,
+ mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void mpz_refgcd (), debug_mp ();
+
+#ifndef SIZE
+#define SIZE 128
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2, x;
+ mpz_t refgcd, gcd, s, t;
+ mpz_t temp1, temp2;
+ mp_size_t op1_size, op2_size, x_size;
+ int i;
+ int reps = 1000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (x);
+ mpz_init (refgcd);
+ mpz_init (gcd);
+ mpz_init (temp1);
+ mpz_init (temp2);
+ mpz_init (s);
+ mpz_init (t);
+
+ for (i = 0; i < reps; i++)
+ {
+ op1_size = urandom () % SIZE - SIZE/2;
+ op2_size = urandom () % SIZE - SIZE/2;
+ x_size = urandom () % SIZE/2;
+
+ mpz_random2 (op1, op1_size);
+ mpz_random2 (op2, op2_size);
+ mpz_random2 (x, x_size);
+ mpz_mul (op1, op1, x);
+ mpz_mul (op2, op2, x);
+
+ mpz_refgcd (refgcd, op1, op2);
+
+ mpz_gcd (gcd, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_gcdext (gcd, s, t, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_mul (temp1, s, op1);
+ mpz_mul (temp2, t, op2);
+ mpz_add (gcd, temp1, temp2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refgcd (g, x, y)
+ mpz_t g;
+ mpz_t x, y;
+{
+ mpz_t xx, yy;
+
+ mpz_init (xx);
+ mpz_init (yy);
+
+ mpz_abs (xx, x);
+ mpz_abs (yy, y);
+
+ for (;;)
+ {
+ if (mpz_cmp_ui (yy, 0) == 0)
+ {
+ mpz_set (g, xx);
+ break;
+ }
+ mpz_tdiv_r (xx, xx, yy);
+ if (mpz_cmp_ui (xx, 0) == 0)
+ {
+ mpz_set (g, yy);
+ break;
+ }
+ mpz_tdiv_r (yy, yy, xx);
+ }
+
+ mpz_clear (xx);
+ mpz_clear (yy);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-mul.c b/gnu/lib/libgmp/mpz/tests/t-mul.c
new file mode 100644
index 0000000..b200cd7
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-mul.c
@@ -0,0 +1,261 @@
+/* Test mpz_add, mpz_cmp, mpz_cmp_ui, mpz_divmod, mpz_mul.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "urandom.h"
+
+void debug_mp ();
+mp_size_t _mpn_mul_classic ();
+void mpz_refmul ();
+
+#ifndef SIZE
+#define SIZE 128
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t multiplier, multiplicand;
+ mpz_t product, ref_product;
+ mpz_t quotient, remainder;
+ mp_size_t multiplier_size, multiplicand_size;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (multiplier);
+ mpz_init (multiplicand);
+ mpz_init (product);
+ mpz_init (ref_product);
+ mpz_init (quotient);
+ mpz_init (remainder);
+
+ for (i = 0; i < reps; i++)
+ {
+ multiplier_size = urandom () % SIZE - SIZE/2;
+ multiplicand_size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (multiplier, multiplier_size);
+ mpz_random2 (multiplicand, multiplicand_size);
+
+ mpz_mul (product, multiplier, multiplicand);
+ mpz_refmul (ref_product, multiplier, multiplicand);
+ if (mpz_cmp_ui (multiplicand, 0) != 0)
+ mpz_divmod (quotient, remainder, product, multiplicand);
+
+ if (mpz_cmp (product, ref_product))
+ dump_abort (multiplier, multiplicand);
+
+ if (mpz_cmp_ui (multiplicand, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) || mpz_cmp (quotient, multiplier))
+ dump_abort (multiplier, multiplicand);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refmul (w, u, v)
+ mpz_t w;
+ const mpz_t u;
+ const mpz_t v;
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize = v->_mp_size;
+ mp_size_t wsize;
+ mp_size_t sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me = NULL;
+ size_t free_me_size;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ /* Swap U and V. */
+ {const __mpz_struct *t = u; u = v; v = t;}
+ {mp_size_t t = usize; usize = vsize; vsize = t;}
+ }
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ wp = w->_mp_d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->_mp_alloc < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = w->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (wp, w->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ w->_mp_alloc = wsize;
+ wp = (mp_ptr) (*_mp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
+ w->_mp_d = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ wsize = _mpn_mul_classic (wp, up, usize, vp, vsize);
+ w->_mp_size = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ TMP_FREE (marker);
+}
+
+mp_size_t
+_mpn_mul_classic (prodp, up, usize, vp, vsize)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_srcptr vp;
+ mp_size_t vsize;
+{
+ mp_size_t i, j;
+ mp_limb_t prod_low, prod_high;
+ mp_limb_t cy_dig;
+ mp_limb_t v_limb, c;
+
+ if (vsize == 0)
+ return 0;
+
+ /* Offset UP and PRODP so that the inner loop can be faster. */
+ up += usize;
+ prodp += usize;
+
+ /* Multiply by the first limb in V separately, as the result can
+ be stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ cy_dig = 0;
+ j = -usize;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prodp[j], prod_high, prod_low, 0, cy_dig);
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++)
+ {
+ v_limb = vp[i];
+ cy_dig = 0;
+ j = -usize;
+
+ /* Inner loops. Simulate the carry flag by jumping between
+ these loops. The first is used when there was no carry
+ in the previois iteration; the second when there was carry. */
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c;
+ prodp[j] = prod_low;
+ if (prod_low < c)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+ continue;
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c + 1;
+ prodp[j] = prod_low;
+ if (prod_low > c)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ cy_dig += 1;
+ prodp[j] = cy_dig;
+ prodp++;
+ }
+
+ return usize + vsize - (cy_dig == 0);
+}
+
+dump_abort (multiplier, multiplicand)
+ mpz_t multiplier, multiplicand;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "multiplier = "); debug_mp (multiplier, -16);
+ fprintf (stderr, "multiplicand = "); debug_mp (multiplicand, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-powm.c b/gnu/lib/libgmp/mpz/tests/t-powm.c
new file mode 100644
index 0000000..02d7ca5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-powm.c
@@ -0,0 +1,125 @@
+/* Test mpz_powm, mpz_mul. mpz_mod, mpz_mod_ui, mpz_div_ui.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t base, exp, mod;
+ mpz_t r1, r2, t1, exp2, base2;
+ mp_size_t base_size, exp_size, mod_size;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (base);
+ mpz_init (exp);
+ mpz_init (mod);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (exp2);
+ mpz_init (base2);
+
+ for (i = 0; i < reps; i++)
+ {
+ base_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (base, base_size);
+
+ exp_size = urandom () % SIZE;
+ mpz_random2 (exp, exp_size);
+
+ mod_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (mod, mod_size);
+ if (mpz_cmp_ui (mod, 0) == 0)
+ continue;
+
+ /* This is mathematically undefined. */
+ if (mpz_cmp_ui (base, 0) == 0 && mpz_cmp_ui (exp, 0) == 0)
+ continue;
+
+#if 0
+ putc ('\n', stderr);
+ debug_mp (base, -16);
+ debug_mp (exp, -16);
+ debug_mp (mod, -16);
+#endif
+
+ mpz_powm (r1, base, exp, mod);
+
+ mpz_set_ui (r2, 1);
+ mpz_set (base2, base);
+ mpz_set (exp2, exp);
+
+ mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */
+ while (mpz_cmp_ui (exp2, 0) != 0)
+ {
+ mpz_mod_ui (t1, exp2, 2);
+ if (mpz_cmp_ui (t1, 0) != 0)
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ mpz_div_ui (exp2, exp2, 2);
+ }
+
+#if 0
+ debug_mp (r1, -16);
+ debug_mp (r2, -16);
+#endif
+
+ if (mpz_cmp (r1, r2) != 0)
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-powm_ui.c b/gnu/lib/libgmp/mpz/tests/t-powm_ui.c
new file mode 100644
index 0000000..b88fa98
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-powm_ui.c
@@ -0,0 +1,120 @@
+/* Test mpz_powm_ui, mpz_mul. mpz_mod, mpz_mod_ui, mpz_div_ui.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t base, mod;
+ mpz_t r1, r2, base2;
+ mp_size_t base_size, mod_size;
+ mp_limb_t exp, exp2;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (base);
+ mpz_init (mod);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (base2);
+
+ for (i = 0; i < reps; i++)
+ {
+ base_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (base, base_size);
+
+ mpn_random2 (&exp, 1);
+
+ mod_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (mod, mod_size);
+ if (mpz_cmp_ui (mod, 0) == 0)
+ continue;
+
+ /* This is mathematically undefined. */
+ if (mpz_cmp_ui (base, 0) == 0 && exp == 0)
+ continue;
+
+#if 0
+ putc ('\n', stderr);
+ debug_mp (base, -16);
+ debug_mp (mod, -16);
+#endif
+
+ mpz_powm_ui (r1, base, (unsigned long int) exp, mod);
+
+ mpz_set_ui (r2, 1);
+ mpz_set (base2, base);
+ exp2 = exp;
+
+ mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */
+ while (exp2 != 0)
+ {
+ if (exp2 % 2 != 0)
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ exp2 = exp2 / 2;
+ }
+
+#if 0
+ debug_mp (r1, -16);
+ debug_mp (r2, -16);
+#endif
+
+ if (mpz_cmp (r1, r2) != 0)
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c b/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c
new file mode 100644
index 0000000..f5fcd09
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c
@@ -0,0 +1,98 @@
+/* Test mpz_add, mpz_add_ui, mpz_cmp, mpz_cmp, mpz_mul, mpz_sqrtrem.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t x2;
+ mpz_t x, rem;
+ mpz_t temp, temp2;
+ mp_size_t x2_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x2);
+ mpz_init (x);
+ mpz_init (rem);
+ mpz_init (temp);
+ mpz_init (temp2);
+
+ for (i = 0; i < reps; i++)
+ {
+ x2_size = urandom () % SIZE;
+
+ mpz_random2 (x2, x2_size);
+
+ mpz_sqrtrem (x, rem, x2);
+ mpz_mul (temp, x, x);
+
+ /* Is square of result > argument? */
+ if (mpz_cmp (temp, x2) > 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add_ui (temp2, x, 1);
+ mpz_mul (temp2, temp2, temp2);
+
+ /* Is square of (result + 1) <= argument? */
+ if (mpz_cmp (temp2, x2) <= 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add (temp2, temp, rem);
+
+ /* Is the remainder wrong? */
+ if (mpz_cmp (x2, temp2) != 0)
+ dump_abort (x2, x, rem);
+ }
+
+ exit (0);
+}
+
+dump_abort (x2, x, rem)
+ mpz_t x2, x, rem;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "x2 = "); debug_mp (x2, -16);
+ fprintf (stderr, "x = "); debug_mp (x, -16);
+ fprintf (stderr, "remainder = "); debug_mp (rem, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-tdiv.c b/gnu/lib/libgmp/mpz/tests/t-tdiv.c
new file mode 100644
index 0000000..d646ed8
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-tdiv.c
@@ -0,0 +1,118 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr, mpz_tdiv_q,
+ mpz_tdiv_r, mpz_mul.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (divisor, divisor_size);
+ if (mpz_cmp_ui (divisor, 0) == 0)
+ continue;
+
+ mpz_tdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_tdiv_q (quotient2, dividend, divisor);
+ mpz_tdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend, divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c b/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c
new file mode 100644
index 0000000..8d73b11
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr_ui, mpz_tdiv_q_ui,
+ mpz_tdiv_r_ui, mpz_mul_ui.
+
+Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ mp_limb_t divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_tdiv_qr_ui (quotient, remainder, dividend, divisor);
+ mpz_tdiv_q_ui (quotient2, dividend, divisor);
+ mpz_tdiv_r_ui (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend;
+ mp_limb_t divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/ui_pow_ui.c b/gnu/lib/libgmp/mpz/ui_pow_ui.c
new file mode 100644
index 0000000..19baca1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/ui_pow_ui.c
@@ -0,0 +1,111 @@
+/* mpz_ui_pow_ui(res, base, exp) -- Set RES to BASE**EXP.
+
+Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#if __STDC__
+mpz_ui_pow_ui (mpz_ptr r, unsigned long int b, unsigned long int e)
+#else
+mpz_ui_pow_ui (r, b, e)
+ mpz_ptr r;
+ unsigned long int b;
+ unsigned long int e;
+#endif
+{
+ mp_ptr rp, tp, xp;
+ mp_size_t rsize;
+ int cnt, i;
+ mp_limb_t blimb = b;
+ TMP_DECL (marker);
+
+ /* Single out cases that give result == 0 or 1. These tests are here
+ to simplify the general code below, not to optimize. */
+ if (e == 0)
+ {
+ r->_mp_d[0] = 1;
+ r->_mp_size = 1;
+ return;
+ }
+ if (blimb == 0)
+ {
+ r->_mp_size = 0;
+ return;
+ }
+
+ if (blimb < 0x100)
+ {
+ /* Estimate space requirements accurately. Using the code from the
+ `else' path would over-estimate space requirements wildly. */
+ float lb = __mp_bases[blimb].chars_per_bit_exactly;
+ rsize = 2 + ((mp_size_t) (e / lb) / BITS_PER_MP_LIMB);
+ }
+ else
+ {
+ /* Over-estimate space requirements somewhat. */
+ count_leading_zeros (cnt, blimb);
+ rsize = e - cnt * e / BITS_PER_MP_LIMB + 1;
+ }
+
+ TMP_MARK (marker);
+
+ /* The two areas are used to alternatingly hold the input and recieve the
+ product for mpn_mul. (This scheme is used to fulfill the requirements
+ of mpn_mul; that the product space may not be the same as any of the
+ input operands.) */
+ rp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+
+ rp[0] = blimb;
+ rsize = 1;
+ count_leading_zeros (cnt, e);
+
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ mpn_mul_n (tp, rp, rp, rsize);
+ rsize = 2 * rsize;
+ rsize -= tp[rsize - 1] == 0;
+ xp = tp; tp = rp; rp = xp;
+
+ if ((e & ((mp_limb_t) 1 << i)) != 0)
+ {
+ mp_limb_t cy;
+ cy = mpn_mul_1 (tp, rp, rsize, blimb);
+ if (cy != 0)
+ {
+ tp[rsize] = cy;
+ rsize++;
+ }
+ xp = tp; tp = rp; rp = xp;
+ }
+ }
+
+ /* Now then we know the exact space requirements, reallocate if
+ necessary. */
+ if (r->_mp_alloc < rsize)
+ _mpz_realloc (r, rsize);
+
+ MPN_COPY (r->_mp_d, rp, rsize);
+ r->_mp_size = rsize;
+ TMP_FREE (marker);
+}
diff --git a/gnu/lib/libgmp/mpz_abs.c b/gnu/lib/libgmp/mpz_abs.c
new file mode 100644
index 0000000..39c1433
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_abs.c
@@ -0,0 +1,44 @@
+/* mpz_abs(MP_INT *dst, MP_INT *src) -- Assign the absolute value of SRC to DST.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_abs (MP_INT *dst, const MP_INT *src)
+#else
+mpz_abs (dst, src)
+ MP_INT *dst;
+ const MP_INT *src;
+#endif
+{
+ mp_size src_size = ABS (src->size);
+
+ if (src != dst)
+ {
+ if (dst->alloc < src_size)
+ _mpz_realloc (dst, src_size);
+
+ MPN_COPY (dst->d, src->d, src_size);
+ }
+
+ dst->size = src_size;
+}
diff --git a/gnu/lib/libgmp/mpz_add.c b/gnu/lib/libgmp/mpz_add.c
new file mode 100644
index 0000000..52639cc
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_add.c
@@ -0,0 +1,121 @@
+/* mpz_add -- Add two integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_add (MP_INT *sum, const MP_INT *u, const MP_INT *v)
+#else
+mpz_add (sum, u, v)
+ MP_INT *sum;
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+madd (const MP_INT *u, const MP_INT *v, MP_INT *sum)
+#else
+madd (u, v, sum)
+ const MP_INT *u;
+ const MP_INT *v;
+ MP_INT *sum;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_srcptr up, vp;
+ mp_ptr sump;
+ mp_size usize, vsize, sumsize;
+ mp_size abs_usize;
+ mp_size abs_vsize;
+
+ usize = u->size;
+ vsize = v->size;
+ abs_usize = ABS (usize);
+ abs_vsize = ABS (vsize);
+
+ if (abs_usize < abs_vsize)
+ {
+ /* Swap U and V. */
+ {const MP_INT *t = u; u = v; v = t;}
+ {mp_size t = usize; usize = vsize; vsize = t;}
+ {mp_size t = abs_usize; abs_usize = abs_vsize; abs_vsize = t;}
+ }
+
+ /* True: abs(USIZE) >= abs(VSIZE) */
+
+ /* If not space for sum (and possible carry), increase space. */
+ sumsize = abs_usize + 1;
+ if (sum->alloc < sumsize)
+ _mpz_realloc (sum, sumsize);
+
+ /* These must be after realloc (u or v may be the same as sum). */
+ up = u->d;
+ vp = v->d;
+ sump = sum->d;
+
+ if (usize >= 0)
+ {
+ if (vsize >= 0)
+ {
+ sumsize = mpn_add (sump, up, abs_usize, vp, abs_vsize);
+ if (sumsize != 0)
+ sump[abs_usize] = 1;
+ sumsize = sumsize + abs_usize;
+ }
+ else
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_usize == abs_vsize && mpn_cmp (up, vp, abs_usize) < 0)
+ sumsize = -(abs_usize
+ + mpn_sub (sump, vp, abs_usize, up, abs_usize));
+ else
+ sumsize = (abs_usize
+ + mpn_sub (sump, up, abs_usize, vp, abs_vsize));
+ }
+ }
+ else
+ {
+ if (vsize >= 0)
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_usize == abs_vsize && mpn_cmp (up, vp, abs_usize) < 0)
+ sumsize = (abs_usize
+ + mpn_sub (sump, vp, abs_usize, up, abs_usize));
+ else
+ sumsize = -(abs_usize
+ + mpn_sub (sump, up, abs_usize, vp, abs_vsize));
+ }
+ else
+ {
+ sumsize = mpn_add (sump, up, abs_usize, vp, abs_vsize);
+ if (sumsize != 0)
+ sump[abs_usize] = 1;
+ sumsize = -(sumsize + abs_usize);
+ }
+ }
+
+ sum->size = sumsize;
+}
diff --git a/gnu/lib/libgmp/mpz_add_ui.c b/gnu/lib/libgmp/mpz_add_ui.c
new file mode 100644
index 0000000..34f754b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_add_ui.c
@@ -0,0 +1,84 @@
+/* mpz_add_ui -- Add an MP_INT and an unsigned one-word integer.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_add_ui (MP_INT *sum, const MP_INT *add1, mp_limb add2)
+#else
+mpz_add_ui (sum, add1, add2)
+ MP_INT *sum;
+ const MP_INT *add1;
+ mp_limb add2;
+#endif
+{
+ mp_srcptr add1p;
+ mp_ptr sump;
+ mp_size add1size, sumsize;
+ mp_size abs_add1size;
+
+ add1size = add1->size;
+ abs_add1size = ABS (add1size);
+
+ /* If not space for SUM (and possible carry), increase space. */
+ sumsize = abs_add1size + 1;
+ if (sum->alloc < sumsize)
+ _mpz_realloc (sum, sumsize);
+
+ /* These must be after realloc (ADD1 may be the same as SUM). */
+ add1p = add1->d;
+ sump = sum->d;
+
+ if (add2 == 0)
+ {
+ MPN_COPY (sump, add1p, abs_add1size);
+ sum->size = add1size;
+ return;
+ }
+ if (abs_add1size == 0)
+ {
+ sump[0] = add2;
+ sum->size = 1;
+ return;
+ }
+
+ if (add1size >= 0)
+ {
+ sumsize = mpn_add (sump, add1p, abs_add1size, &add2, 1);
+ if (sumsize != 0)
+ sump[abs_add1size] = 1;
+ sumsize = sumsize + abs_add1size;
+ }
+ else
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_add1size == 1 && add1p[0] < add2)
+ sumsize = (abs_add1size
+ + mpn_sub (sump, &add2, 1, add1p, 1));
+ else
+ sumsize = -(abs_add1size
+ + mpn_sub (sump, add1p, abs_add1size, &add2, 1));
+ }
+
+ sum->size = sumsize;
+}
diff --git a/gnu/lib/libgmp/mpz_and.c b/gnu/lib/libgmp/mpz_and.c
new file mode 100644
index 0000000..f5b39ed
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_and.c
@@ -0,0 +1,267 @@
+/* mpz_and -- Logical and.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define min(l,o) ((l) < (o) ? (l) : (o))
+#define max(h,i) ((h) > (i) ? (h) : (i))
+
+void
+#ifdef __STDC__
+mpz_and (MP_INT *res, const MP_INT *op1, const MP_INT *op2)
+#else
+mpz_and (res, op1, op2)
+ MP_INT *res;
+ const MP_INT *op1;
+ const MP_INT *op2;
+#endif
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size res_size;
+ mp_size i;
+
+ op1_size = op1->size;
+ op2_size = op2->size;
+
+ op1_ptr = op1->d;
+ op2_ptr = op2->d;
+ res_ptr = res->d;
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ res_size = min (op1_size, op2_size);
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now when we know exactly how much space is
+ needed for the result. */
+ if (res->alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ op1_ptr = op1->d;
+ op2_ptr = op2->d;
+ res_ptr = res->d;
+ }
+
+ /* Second loop computes the real result. */
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & op2_ptr[i];
+
+ res->size = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ /* Fall through to the code at the end of the function. */
+ ;
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx;
+ mp_limb cy;
+ mp_limb one = 1;
+ mp_size res_alloc;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) & (-OP2)) = -(~(OP1 - 1) & ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) & ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) | (OP2 - 1)) + 1 */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ res_alloc = 1 + max (op1_size, op2_size);
+
+ opx = (mp_ptr) alloca (op1_size * BYTES_PER_MP_LIMB);
+ op1_size += mpn_sub (opx, op1_ptr, op1_size, &one, 1);
+ op1_ptr = opx;
+
+ opx = (mp_ptr) alloca (op2_size * BYTES_PER_MP_LIMB);
+ op2_size += mpn_sub (opx, op2_ptr, op2_size, &one, 1);
+ op2_ptr = opx;
+
+ if (res->alloc < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ res_ptr = res->d;
+ /* Don't re-read OP1_PTR and OP2_PTR. They point to
+ temporary space--never to the space RES->D used
+ to point to before reallocation. */
+ }
+
+ if (op1_size >= op2_size)
+ {
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op1_size;
+ }
+ else
+ {
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ for (i = op1_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op2_size;
+ }
+
+ if (res_size != 0)
+ {
+ cy = mpn_add (res_ptr, res_ptr, res_size, &one, 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ res->size = -res_size;
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 & OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 & -OP2. */
+ {const MP_INT *t = op1; op1 = op2; op2 = t;}
+ {mp_srcptr t = op1_ptr; op1_ptr = op2_ptr; op2_ptr = t;}
+ {mp_size t = op1_size; op1_size = op2_size; op2_size = t;}
+ }
+
+ }
+
+ {
+#if 0
+ mp_size op2_lim;
+
+ /* OP2 must be negated as with infinite precision.
+
+ Scan from the low end for a non-zero limb. The first non-zero
+ limb is simply negated (two's complement). Any subsequent
+ limbs are one's complemented. Of course, we don't need to
+ handle more limbs than there are limbs in the other, positive
+ operand as the result for those limbs is going to become zero
+ anyway. */
+
+ /* Scan for the least significant. non-zero OP2 limb, and zero the
+ result meanwhile for those limb positions. (We will surely
+ find a non-zero limb, so we can write the loop with one
+ termination condition only.) */
+ for (i = 0; op2_ptr[i] == 0; i++)
+ res_ptr[i] = 0;
+ op2_lim = i;
+
+ op2_size = -op2_size;
+
+ if (op1_size <= op2_size)
+ {
+ /* The ones-extended OP2 is >= than the zero-extended OP1.
+ RES_SIZE <= OP1_SIZE. Find the exact size. */
+ for (i = op1_size - 1; i > op2_lim; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ }
+ else
+ {
+ /* The ones-extended OP2 is < than the zero-extended OP1.
+ RES_SIZE == OP1_SIZE, since OP1 is normalized. */
+ res_size = op1_size;
+ }
+#endif
+
+ /* OP1 is positive and zero-extended,
+ OP2 is negative and ones-extended.
+ The result will be positive.
+ OP1 & -OP2 = OP1 & ~(OP2 - 1). */
+
+ mp_ptr opx;
+ const mp_limb one = 1;
+
+ op2_size = -op2_size;
+ opx = (mp_ptr) alloca (op2_size * BYTES_PER_MP_LIMB);
+ op2_size += mpn_sub (opx, op2_ptr, op2_size, &one, 1);
+ op2_ptr = opx;
+
+ if (op1_size > op2_size)
+ {
+ /* The result has the same size as OP1, since OP1 is normalized
+ and longer than the ones-extended OP2. */
+ res_size = op1_size;
+
+ /* Handle allocation, now when we know exactly how much space is
+ needed for the result. */
+ if (res->alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->d;
+ op1_ptr = op1->d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->D used to point to before reallocation. */
+ }
+
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ res_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+
+ res->size = res_size;
+ }
+ else
+ {
+ /* Find out the exact result size. Ignore the high limbs of OP2,
+ OP1 is zero-extended and would make the result zero. */
+ for (i = op1_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & ~op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Handle allocation, now when we know exactly how much space is
+ needed for the result. */
+ if (res->alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->d;
+ op1_ptr = op1->d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->D used to point to before reallocation. */
+ }
+
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & ~op2_ptr[i];
+
+ res->size = res_size;
+ }
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_clear.c b/gnu/lib/libgmp/mpz_clear.c
new file mode 100644
index 0000000..f95b009
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_clear.c
@@ -0,0 +1,34 @@
+/* mpz_clear -- de-allocate the space occupied by the dynamic digit space of
+ an integer.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_clear (MP_INT *m)
+#else
+mpz_clear (m)
+ MP_INT *m;
+#endif
+{
+ (*_mp_free_func) (m->d, m->alloc * BYTES_PER_MP_LIMB);
+}
diff --git a/gnu/lib/libgmp/mpz_clrbit.c b/gnu/lib/libgmp/mpz_clrbit.c
new file mode 100644
index 0000000..7fde814
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_clrbit.c
@@ -0,0 +1,124 @@
+/* mpz_clrbit -- clear a specified bit.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define MPN_NORMALIZE(p, size) \
+ do { \
+ mp_size i; \
+ for (i = (size) - 1; i >= 0; i--) \
+ if ((p)[i] != 0) \
+ break; \
+ (size) = i + 1; \
+ } while (0)
+
+void
+#ifdef __STDC__
+mpz_clrbit (MP_INT *d, unsigned long int bit_index)
+#else
+mpz_clrbit (d, bit_index)
+ MP_INT *d;
+ unsigned long int bit_index;
+#endif
+{
+ mp_size dsize = d->size;
+ mp_ptr dp = d->d;
+ mp_size limb_index;
+
+ limb_index = bit_index / BITS_PER_MP_LIMB;
+ if (dsize >= 0)
+ {
+ if (limb_index < dsize)
+ {
+ dp[limb_index] &= ~((mp_limb) 1 << (bit_index % BITS_PER_MP_LIMB));
+ MPN_NORMALIZE (dp, dsize);
+ d->size = dsize;
+ }
+ else
+ ;
+ }
+ else
+ {
+ mp_size zero_bound;
+
+ /* Simulate two's complement arithmetic, i.e. simulate
+ 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
+ 2. clear the bit.
+ 3. Set OP = ~OP + 1. */
+
+ dsize = -dsize;
+
+ /* No upper bound on this loop, we're sure there's a non-zero limb
+ sooner ot later. */
+ for (zero_bound = 0; ; zero_bound++)
+ if (dp[zero_bound] != 0)
+ break;
+
+ if (limb_index > zero_bound)
+ {
+ if (limb_index < dsize)
+ {
+ dp[limb_index] |= ((mp_limb) 1 << (bit_index % BITS_PER_MP_LIMB));
+ }
+ else
+ {
+ /* Ugh. The bit should be cleared outside of the end of the
+ number. We have to increase the size of the number. */
+ if (d->alloc < limb_index + 1)
+ {
+ _mpz_realloc (d, limb_index + 1);
+ dp = d->d;
+ }
+ MPN_ZERO (dp + dsize, limb_index - dsize);
+ dp[limb_index] = ((mp_limb) 1 << (bit_index % BITS_PER_MP_LIMB));
+ d->size = -(limb_index + 1);
+ }
+ }
+ else if (limb_index == zero_bound)
+ {
+ dp[limb_index] = ((dp[limb_index] - 1)
+ | ((mp_limb) 1 << (bit_index % BITS_PER_MP_LIMB))) + 1;
+ if (dp[limb_index] == 0)
+ {
+ mp_size i;
+ for (i = limb_index + 1; i < dsize; i++)
+ {
+ dp[i] += 1;
+ if (dp[i] != 0)
+ goto fin;
+ }
+ /* We got carry all way out beyond the end of D. Increase
+ its size (and allocation if necessary). */
+ dsize++;
+ if (d->alloc < dsize)
+ {
+ _mpz_realloc (d, dsize);
+ dp = d->d;
+ }
+ dp[i] = 1;
+ d->size = -dsize;
+ fin:;
+ }
+ }
+ else
+ ;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_cmp.c b/gnu/lib/libgmp/mpz_cmp.c
new file mode 100644
index 0000000..b76b494
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_cmp.c
@@ -0,0 +1,84 @@
+/* mpz_cmp(u,v) -- Compare U, V. Return postive, zero, or negative
+ based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef BERKELEY_MP
+#include "mp.h"
+#endif
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+int
+#ifdef __STDC__
+mpz_cmp (const MP_INT *u, const MP_INT *v)
+#else
+mpz_cmp (u, v)
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#else /* BERKELEY_MP */
+int
+#ifdef __STDC__
+mcmp (const MP_INT *u, const MP_INT *v)
+#else
+mcmp (u, v)
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size usize = u->size;
+ mp_size vsize = v->size;
+ mp_size size;
+ mp_size i;
+ mp_limb a, b;
+ mp_srcptr up, vp;
+
+ if (usize != vsize)
+ return usize - vsize;
+
+ if (usize == 0)
+ return 0;
+
+ size = ABS (usize);
+
+ up = u->d;
+ vp = v->d;
+
+ i = size - 1;
+ do
+ {
+ a = up[i];
+ b = vp[i];
+ i--;
+ if (i < 0)
+ break;
+ }
+ while (a == b);
+
+ if (a == b)
+ return 0;
+
+ if ((a < b) == (usize < 0))
+ return 1;
+ else
+ return -1;
+}
diff --git a/gnu/lib/libgmp/mpz_cmp_si.c b/gnu/lib/libgmp/mpz_cmp_si.c
new file mode 100644
index 0000000..c7073be
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_cmp_si.c
@@ -0,0 +1,62 @@
+/* mpz_cmp_si(u,v) -- Compare an integer U with a single-word int V.
+ Return positive, zero, or negative based on if U > V, U == V, or U < V.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#ifdef __STDC__
+mpz_cmp_si (const MP_INT *u, signed long int v_digit)
+#else
+mpz_cmp_si (u, v_digit)
+ const MP_INT *u;
+ signed long int v_digit;
+#endif
+{
+ mp_size usize = u->size;
+ mp_size vsize;
+ mp_limb u_digit;
+
+ vsize = 0;
+ if (v_digit > 0)
+ vsize = 1;
+ else if (v_digit < 0)
+ {
+ vsize = -1;
+ v_digit = -v_digit;
+ }
+
+ if (usize != vsize)
+ return usize - vsize;
+
+ if (usize == 0)
+ return 0;
+
+ u_digit = u->d[0];
+
+ if (u_digit == v_digit)
+ return 0;
+
+ if ((u_digit < v_digit) == (usize < 0))
+ return 1;
+ else
+ return -1;
+}
diff --git a/gnu/lib/libgmp/mpz_cmp_ui.c b/gnu/lib/libgmp/mpz_cmp_ui.c
new file mode 100644
index 0000000..79a41db
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_cmp_ui.c
@@ -0,0 +1,52 @@
+/* mpz_cmp_ui.c -- Compare a MP_INT a with an mp_limb b. Return positive,
+ zero, or negative based on if a > b, a == b, or a < b.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#ifdef __STDC__
+mpz_cmp_ui (const MP_INT *u, mp_limb v_digit)
+#else
+mpz_cmp_ui (u, v_digit)
+ const MP_INT *u;
+ mp_limb v_digit;
+#endif
+{
+ mp_size usize = u->size;
+
+ if (usize == 0)
+ return -(v_digit != 0);
+
+ if (usize == 1)
+ {
+ mp_limb u_digit;
+
+ u_digit = u->d[0];
+ if (u_digit > v_digit)
+ return 1;
+ if (u_digit < v_digit)
+ return -1;
+ return 0;
+ }
+
+ return (usize > 0) ? 1 : -1;
+}
diff --git a/gnu/lib/libgmp/mpz_com.c b/gnu/lib/libgmp/mpz_com.c
new file mode 100644
index 0000000..3c0d3b1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_com.c
@@ -0,0 +1,96 @@
+/* mpz_com(MP_INT *dst, MP_INT *src) -- Assign the bit-complemented value of
+ SRC to DST.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_com (MP_INT *dst, const MP_INT *src)
+#else
+mpz_com (dst, src)
+ MP_INT *dst;
+ const MP_INT *src;
+#endif
+{
+ mp_size size = src->size;
+ mp_srcptr src_ptr;
+ mp_ptr dst_ptr;
+
+ if (size >= 0)
+ {
+ /* As with infinite precision: one's complement, two's complement.
+ But this can be simplified using the identity -x = ~x + 1.
+ So we're going to compute (~~x) + 1 = x + 1! */
+
+ if (dst->alloc < size + 1)
+ _mpz_realloc (dst, size + 1);
+
+ src_ptr = src->d;
+ dst_ptr = dst->d;
+
+ if (size == 0)
+ {
+ /* Special case, as mpn_add wants the first arg's size >= the
+ second arg's size. */
+ dst_ptr[0] = 1;
+ dst->size = -1;
+ return;
+ }
+
+ {
+ mp_limb one = 1;
+ int cy;
+
+ cy = mpn_add (dst_ptr, src_ptr, size, &one, 1);
+ if (cy)
+ {
+ dst_ptr[size] = cy;
+ size++;
+ }
+ }
+
+ /* Store a negative size, to indicate ones-extension. */
+ dst->size = -size;
+ }
+ else
+ {
+ /* As with infinite precision: two's complement, then one's complement.
+ But that can be simplified using the identity -x = ~(x - 1).
+ So we're going to compute ~~(x - 1) = x - 1! */
+ size = -size;
+
+ if (dst->alloc < size)
+ _mpz_realloc (dst, size);
+
+ src_ptr = src->d;
+ dst_ptr = dst->d;
+
+ {
+ mp_limb one = 1;
+
+ size += mpn_sub (dst_ptr, src_ptr, size, &one, 1);
+ }
+
+ /* Store a positive size, to indicate zero-extension. */
+ dst->size = size;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_div.c b/gnu/lib/libgmp/mpz_div.c
new file mode 100644
index 0000000..a27cde9
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_div.c
@@ -0,0 +1,117 @@
+/* mpz_div -- divide two integers and produce a quotient.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_div (MP_INT *quot, const MP_INT *num, const MP_INT *den)
+#else
+mpz_div (quot, num, den)
+ MP_INT *quot;
+ const MP_INT *num;
+ const MP_INT *den;
+#endif
+{
+ mp_srcptr np, dp;
+ mp_ptr qp, rp;
+ mp_size nsize = num->size;
+ mp_size dsize = den->size;
+ mp_size qsize, rsize;
+ mp_size sign_quotient = nsize ^ dsize;
+ unsigned normalization_steps;
+
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+
+ /* Ensure space is enough for quotient. */
+
+ qsize = nsize - dsize + 1; /* qsize cannot be bigger than this. */
+ if (qsize <= 0)
+ {
+ quot->size = 0;
+ return;
+ }
+
+ if (quot->alloc < qsize)
+ _mpz_realloc (quot, qsize);
+
+ qp = quot->d;
+ np = num->d;
+ dp = den->d;
+ rp = (mp_ptr) alloca ((nsize + 1) * BYTES_PER_MP_LIMB);
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator and the numerator. */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb ndigit;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant word. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) alloca (dsize * BYTES_PER_MP_LIMB);
+ (void) mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ significant word. Move the shifted numerator in the remainder
+ meanwhile. */
+ ndigit = mpn_lshift (rp, np, nsize, normalization_steps);
+ if (ndigit != 0)
+ {
+ rp[nsize] = ndigit;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else
+ {
+ /* The denominator is already normalized, as required.
+ Copy it to temporary space if it overlaps with the quotient. */
+ if (dp == qp)
+ {
+ dp = (mp_ptr) alloca (dsize * BYTES_PER_MP_LIMB);
+ MPN_COPY ((mp_ptr) dp, qp, dsize);
+ }
+
+ /* Move the numerator to the remainder. */
+ MPN_COPY (rp, np, nsize);
+ rsize = nsize;
+ }
+
+ qsize = rsize - dsize + mpn_div (qp, rp, rsize, dp, dsize);
+
+ /* Normalize the quotient. We may have at most one leading
+ zero-word, so no loop is needed. */
+ if (qsize > 0)
+ qsize -= (qp[qsize - 1] == 0);
+
+ if (sign_quotient < 0)
+ qsize = -qsize;
+ quot->size = qsize;
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_div_2exp.c b/gnu/lib/libgmp/mpz_div_2exp.c
new file mode 100644
index 0000000..de67f2f
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_div_2exp.c
@@ -0,0 +1,53 @@
+/* mpz_div_2exp -- Divide a bignum by 2**CNT
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_div_2exp (MP_INT *w, const MP_INT *u, unsigned long int cnt)
+#else
+mpz_div_2exp (w, u, cnt)
+ MP_INT *w;
+ const MP_INT *u;
+ unsigned long int cnt;
+#endif
+{
+ mp_size usize = u->size;
+ mp_size wsize;
+ mp_size abs_usize = ABS (usize);
+ mp_size limb_cnt;
+
+ limb_cnt = cnt / BITS_PER_MP_LIMB;
+ wsize = abs_usize - limb_cnt;
+ if (wsize <= 0)
+ wsize = 0;
+ else
+ {
+ if (w->alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ wsize = mpn_rshift (w->d, u->d + limb_cnt, abs_usize - limb_cnt,
+ cnt % BITS_PER_MP_LIMB);
+ }
+
+ w->size = (usize >= 0) ? wsize : -wsize;
+}
diff --git a/gnu/lib/libgmp/mpz_div_ui.c b/gnu/lib/libgmp/mpz_div_ui.c
new file mode 100644
index 0000000..93c2552
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_div_ui.c
@@ -0,0 +1,65 @@
+/* mpz_div_ui(quot, dividend, divisor_limb)
+ -- Divide DIVIDEND by DIVISOR_LIMB and store the result in QUOT.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_div_ui (MP_INT *quot, const MP_INT *dividend, unsigned long int divisor_limb)
+#else
+mpz_div_ui (quot, dividend, divisor_limb)
+ MP_INT *quot;
+ const MP_INT *dividend;
+ unsigned long int divisor_limb;
+#endif
+{
+ mp_size sign_dividend;
+ mp_size dividend_size, quot_size;
+ mp_ptr dividend_ptr, quot_ptr;
+
+ sign_dividend = dividend->size;
+ dividend_size = ABS (dividend->size);
+
+ if (dividend_size == 0)
+ {
+ quot->size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->alloc < dividend_size)
+ _mpz_realloc (quot, dividend_size);
+
+ quot_ptr = quot->d;
+ dividend_ptr = dividend->d;
+
+ mpn_divmod_1 (quot_ptr, dividend_ptr, dividend_size, divisor_limb);
+
+ /* The quotient is DIVIDEND_SIZE limbs, but the most significant
+ might be zero. Set QUOT_SIZE properly. */
+ quot_size = dividend_size - (quot_ptr[dividend_size - 1] == 0);
+ quot->size = sign_dividend >= 0 ? quot_size : -quot_size;
+}
diff --git a/gnu/lib/libgmp/mpz_dm.c b/gnu/lib/libgmp/mpz_dm.c
new file mode 100644
index 0000000..26fda05
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_dm.c
@@ -0,0 +1,38 @@
+/* mpz_divmod(quot,rem,dividend,divisor) -- Set QUOT to DIVIDEND/DIVISOR,
+ and REM to DIVIDEND mod DIVISOR.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_divmod (MP_INT *quot, MP_INT *rem, const MP_INT *num, const MP_INT *den)
+#else
+mpz_divmod (quot, rem, num, den)
+ MP_INT *quot;
+ MP_INT *rem;
+ const MP_INT *num;
+ const MP_INT *den;
+#endif
+
+#define COMPUTE_QUOTIENT
+#include "mpz_dmincl.c"
diff --git a/gnu/lib/libgmp/mpz_dm_ui.c b/gnu/lib/libgmp/mpz_dm_ui.c
new file mode 100644
index 0000000..e8c3cf6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_dm_ui.c
@@ -0,0 +1,81 @@
+/* mpz_divmod_ui(quot,rem,dividend,short_divisor) --
+ Set QUOT to DIVIDEND / SHORT_DIVISOR
+ and REM to DIVIDEND mod SHORT_DIVISOR.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_divmod_ui (MP_INT *quot, MP_INT *rem,
+ const MP_INT *dividend, unsigned long int divisor_limb)
+#else
+mpz_divmod_ui (quot, rem, dividend, divisor_limb)
+ MP_INT *quot;
+ MP_INT *rem;
+ const MP_INT *dividend;
+ unsigned long int divisor_limb;
+#endif
+{
+ mp_size sign_dividend;
+ mp_size dividend_size, quot_size;
+ mp_ptr dividend_ptr, quot_ptr;
+ mp_limb remainder_limb;
+
+ sign_dividend = dividend->size;
+ dividend_size = ABS (dividend->size);
+
+ if (dividend_size == 0)
+ {
+ quot->size = 0;
+ rem->size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->alloc < dividend_size)
+ _mpz_realloc (quot, dividend_size);
+
+ quot_ptr = quot->d;
+ dividend_ptr = dividend->d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr,
+ dividend_ptr, dividend_size, divisor_limb);
+
+ if (remainder_limb == 0)
+ rem->size = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ rem->size = sign_dividend >= 0 ? 1 : -1;
+ rem->d[0] = remainder_limb;
+ }
+
+ /* The quotient is DIVIDEND_SIZE limbs, but the most significant
+ might be zero. Set QUOT_SIZE properly. */
+ quot_size = dividend_size - (quot_ptr[dividend_size - 1] == 0);
+ quot->size = sign_dividend >= 0 ? quot_size : -quot_size;
+}
diff --git a/gnu/lib/libgmp/mpz_dmincl.c b/gnu/lib/libgmp/mpz_dmincl.c
new file mode 100644
index 0000000..dde7981
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_dmincl.c
@@ -0,0 +1,172 @@
+/* mpz_dmincl.c -- include file for mpz_dm.c, mpz_mod.c, mdiv.c.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* THIS CODE IS OBSOLETE. IT WILL SOON BE REPLACED BY CLEANER CODE WITH
+ LESS MEMORY ALLOCATION OVERHEAD. */
+
+/* If den == quot, den needs temporary storage.
+ If den == rem, den needs temporary storage.
+ If num == quot, num needs temporary storage.
+ If den has temporary storage, it can be normalized while being copied,
+ i.e no extra storage should be allocated. */
+
+/* This is the function body of mdiv, mpz_divmod, and mpz_mod.
+
+ If COMPUTE_QUOTIENT is defined, the quotient is put in the MP_INT
+ object quot, otherwise that variable is not referenced at all.
+
+ The remainder is always computed, and the result is put in the MP_INT
+ object rem. */
+
+{
+ mp_ptr np, dp;
+ mp_ptr qp, rp;
+ mp_size nsize = num->size;
+ mp_size dsize = den->size;
+ mp_size qsize, rsize;
+ mp_size sign_remainder = nsize;
+#ifdef COMPUTE_QUOTIENT
+ mp_size sign_quotient = nsize ^ dsize;
+#endif
+ unsigned normalization_steps;
+
+ nsize = ABS (nsize);
+ dsize = ABS (dsize);
+
+ /* Ensure space is enough for quotient and remainder. */
+
+ /* We need space for an extra limb in the remainder, because it's
+ up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ if (rem->alloc < rsize)
+ _mpz_realloc (rem, rsize);
+
+ qsize = nsize - dsize + 1; /* qsize cannot be bigger than this. */
+ if (qsize <= 0)
+ {
+#ifdef COMPUTE_QUOTIENT
+ quot->size = 0;
+#endif
+ if (num != rem)
+ {
+ rem->size = num->size;
+ MPN_COPY (rem->d, num->d, nsize);
+ }
+ return;
+ }
+
+#ifdef COMPUTE_QUOTIENT
+ if (quot->alloc < qsize)
+ _mpz_realloc (quot, qsize);
+ qp = quot->d;
+#else
+ qp = (mp_ptr) alloca (qsize * BYTES_PER_MP_LIMB);
+#endif
+ np = num->d;
+ dp = den->d;
+ rp = rem->d;
+
+ /* Make sure quot and num are different. Otherwise the numerator
+ would be successively overwritten by the quotient digits. */
+ if (qp == np)
+ {
+ np = (mp_ptr) alloca (nsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (np, qp, nsize);
+ }
+
+ count_leading_zeros (normalization_steps, dp[dsize - 1]);
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ numerator the same number of steps (to keep the quotient the same!). */
+ if (normalization_steps != 0)
+ {
+ mp_ptr tp;
+ mp_limb ndigit;
+
+ /* Shift up the denominator setting the most significant bit of
+ the most significant word. Use temporary storage not to clobber
+ the original contents of the denominator. */
+ tp = (mp_ptr) alloca (dsize * BYTES_PER_MP_LIMB);
+ (void) mpn_lshift (tp, dp, dsize, normalization_steps);
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ significant word. Move the shifted numerator in the remainder
+ meanwhile. */
+ ndigit = mpn_lshift (rp, np, nsize, normalization_steps);
+ if (ndigit != 0)
+ {
+ rp[nsize] = ndigit;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else
+ {
+#ifdef COMPUTE_QUOTIENT
+ if (rem == den || quot == den)
+#else
+ if (rem == den)
+#endif
+ {
+ mp_ptr tp;
+
+ tp = (mp_ptr) alloca (dsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (tp, dp, dsize);
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if (rp != np)
+ MPN_COPY (rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ qsize = rsize - dsize + mpn_div (qp, rp, rsize, dp, dsize);
+
+ rsize = dsize;
+
+ /* Normalize the remainder. */
+ while (rsize > 0)
+ {
+ if (rp[rsize - 1] != 0)
+ break;
+ rsize--;
+ }
+
+ if (normalization_steps != 0)
+ rsize = mpn_rshift (rp, rp, rsize, normalization_steps);
+
+ rem->size = (sign_remainder >= 0) ? rsize : -rsize;
+
+#ifdef COMPUTE_QUOTIENT
+ /* Normalize the quotient. We may have at most one leading
+ zero-word, so no loop is needed. */
+ if (qsize > 0)
+ qsize -= (qp[qsize - 1] == 0);
+
+ quot->size = (sign_quotient >= 0) ? qsize : -qsize;
+#endif
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_fac_ui.c b/gnu/lib/libgmp/mpz_fac_ui.c
new file mode 100644
index 0000000..9cdc785
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_fac_ui.c
@@ -0,0 +1,156 @@
+/* mpz_fac_ui(result, n) -- Set RESULT to N!.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef DBG
+#include <stdio.h>
+#endif
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_fac_ui (MP_INT *result, unsigned long int n)
+#else
+mpz_fac_ui (result, n)
+ MP_INT *result;
+ unsigned long int n;
+#endif
+{
+#if SIMPLE_FAC
+
+ /* Be silly. Just multiply the numbers in ascending order. O(n**2). */
+
+ mp_limb k;
+
+ mpz_set_ui (result, (mp_limb) 1);
+
+ for (k = 2; k <= n; k++)
+ mpz_mul_ui (result, result, k);
+#else
+
+ /* Be smarter. Multiply groups of numbers in ascending order until the
+ product doesn't fit in a limb. Multiply these partial products in a
+ balanced binary tree fashion, to make the operand have as equal sizes
+ as possible. (When the operands have about the same size, mpn_mul
+ becomes faster.) */
+
+ mp_limb k;
+ mp_limb p1, p0, p;
+
+ /* Stack of partial products, used to make the computation balanced
+ (i.e. make the sizes of the multiplication operands equal). The
+ topmost position of MP_STACK will contain a one-limb partial product,
+ the second topmost will contain a two-limb partial product, and so
+ on. MP_STACK[0] will contain a partial product with 2**t limbs.
+ To compute n! MP_STACK needs to be less than
+ log(n)**2/log(BITS_PER_MP_LIMB), so 30 is surely enough. */
+#define MP_STACK_SIZE 30
+ MP_INT mp_stack[MP_STACK_SIZE];
+
+ /* TOP is an index into MP_STACK, giving the topmost element.
+ TOP_LIMIT_SO_FAR is the largets value it has taken so far. */
+ int top, top_limit_so_far;
+
+ /* Count of the total number of limbs put on MP_STACK so far. This
+ variable plays an essential role in making the compututation balanced.
+ See below. */
+ unsigned int tree_cnt;
+
+ top = top_limit_so_far = -1;
+ tree_cnt = 0;
+ p = 1;
+ for (k = 2; k <= n; k++)
+ {
+ /* Multiply the partial product in P with K. */
+ umul_ppmm (p1, p0, p, k);
+
+ /* Did we get overflow into the high limb, i.e. is the partial
+ product now more than one limb? */
+ if (p1 != 0)
+ {
+ tree_cnt++;
+
+ if (tree_cnt % 2 == 0)
+ {
+ mp_size i;
+
+ /* TREE_CNT is even (i.e. we have generated an even number of
+ one-limb partial products), which means that we have a
+ single-limb product on the top of MP_STACK. */
+
+ mpz_mul_ui (&mp_stack[top], &mp_stack[top], p);
+
+ /* If TREE_CNT is divisable by 4, 8,..., we have two
+ similar-sized partial products with 2, 4,... limbs at
+ the topmost two positions of MP_STACK. Multiply them
+ to form a new partial product with 4, 8,... limbs. */
+ for (i = 4; (tree_cnt & (i - 1)) == 0; i <<= 1)
+ {
+ mpz_mul (&mp_stack[top - 1],
+ &mp_stack[top], &mp_stack[top - 1]);
+ top--;
+ }
+ }
+ else
+ {
+ /* Put the single-limb partial product in P on the stack.
+ (The next time we get a single-limb product, we will
+ multiply the two together.) */
+ top++;
+ if (top > top_limit_so_far)
+ {
+ if (top > MP_STACK_SIZE)
+ abort();
+ /* The stack is now bigger than ever, initialize the top
+ element. */
+ mpz_init_set_ui (&mp_stack[top], p);
+ top_limit_so_far++;
+ }
+ else
+ mpz_set_ui (&mp_stack[top], p);
+ }
+
+ /* We ignored the last result from umul_ppmm. Put K in P as the
+ first component of the next single-limb partial product. */
+ p = k;
+ }
+ else
+ /* We didn't get overflow in umul_ppmm. Put p0 in P and try
+ with one more value of K. */
+ p = p0;
+ }
+
+ /* We have partial products in mp_stack[0..top], in descending order.
+ We also have a small partial product in p.
+ Their product is the final result. */
+ if (top < 0)
+ mpz_set_ui (result, p);
+ else
+ mpz_mul_ui (result, &mp_stack[top--], p);
+ while (top >= 0)
+ mpz_mul (result, result, &mp_stack[top--]);
+
+ /* Free the storage allocated for MP_STACK. */
+ for (top = top_limit_so_far; top >= 0; top--)
+ mpz_clear (&mp_stack[top]);
+#endif
+}
diff --git a/gnu/lib/libgmp/mpz_gcd.c b/gnu/lib/libgmp/mpz_gcd.c
new file mode 100644
index 0000000..090c8c5
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_gcd.c
@@ -0,0 +1,169 @@
+/* mpz_gcd -- Calculate the greatest common divisior of two integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_gcd (MP_INT *w, const MP_INT *u, const MP_INT *v)
+#else
+mpz_gcd (w, u, v)
+ MP_INT *w;
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+gcd (const MP_INT *u, const MP_INT *v, MP_INT *w)
+#else
+gcd (u, v, w)
+ const MP_INT *u;
+ const MP_INT *v;
+ MP_INT *w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size usize, vsize, wsize;
+ mp_ptr up_in, vp_in;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_size i;
+ mp_limb d;
+ int bcnt;
+ mp_size w_bcnt;
+ mp_limb cy_digit;
+
+ usize = ABS (u->size);
+ vsize = ABS (v->size);
+
+ /* GCD(0,v) == v. */
+ if (usize == 0)
+ {
+ if (w->alloc < vsize)
+ _mpz_realloc (w, vsize);
+
+ w->size = vsize;
+ MPN_COPY (w->d, v->d, vsize);
+ return;
+ }
+
+ /* GCD(0,u) == u. */
+ if (vsize == 0)
+ {
+ if (w->alloc < usize)
+ _mpz_realloc (w, usize);
+
+ w->size = usize;
+ MPN_COPY (w->d, u->d, usize);
+ return;
+ }
+
+ /* Make U odd by shifting it down as many bit positions as there
+ are zero bits. Put the result in temporary space. */
+ up = (mp_ptr) alloca (usize * BYTES_PER_MP_LIMB);
+ up_in = u->d;
+ for (i = 0; (d = up_in[i]) == 0; i++)
+ ;
+ count_leading_zeros (bcnt, d & -d);
+ bcnt = BITS_PER_MP_LIMB - 1 - bcnt;
+ usize = mpn_rshift (up, up_in + i, usize - i, bcnt);
+
+ bcnt += i * BITS_PER_MP_LIMB;
+ w_bcnt = bcnt;
+
+ /* Make V odd by shifting it down as many bit positions as there
+ are zero bits. Put the result in temporary space. */
+ vp = (mp_ptr) alloca (vsize * BYTES_PER_MP_LIMB);
+ vp_in = v->d;
+ for (i = 0; (d = vp_in[i]) == 0; i++)
+ ;
+ count_leading_zeros (bcnt, d & -d);
+ bcnt = BITS_PER_MP_LIMB - 1 - bcnt;
+ vsize = mpn_rshift (vp, vp_in + i, vsize - i, bcnt);
+
+ /* W_BCNT is set to the minimum of the number of zero bits in U and V.
+ Thus it represents the number of common 2 factors. */
+ bcnt += i * BITS_PER_MP_LIMB;
+ if (bcnt < w_bcnt)
+ w_bcnt = bcnt;
+
+ for (;;)
+ {
+ int cmp;
+
+ cmp = usize - vsize != 0 ? usize - vsize : mpn_cmp (up, vp, usize);
+
+ /* If U and V have become equal, we have found the GCD. */
+ if (cmp == 0)
+ break;
+
+ if (cmp > 0)
+ {
+ /* Replace U by (U - V) >> cnt, with cnt being the least value
+ making U odd again. */
+
+ usize += mpn_sub (up, up, usize, vp, vsize);
+ for (i = 0; (d = up[i]) == 0; i++)
+ ;
+ count_leading_zeros (bcnt, d & -d);
+ bcnt = BITS_PER_MP_LIMB - 1 - bcnt;
+ usize = mpn_rshift (up, up + i, usize - i, bcnt);
+ }
+ else
+ {
+ /* Replace V by (V - U) >> cnt, with cnt being the least value
+ making V odd again. */
+
+ vsize += mpn_sub (vp, vp, vsize, up, usize);
+ for (i = 0; (d = vp[i]) == 0; i++)
+ ;
+ count_leading_zeros (bcnt, d & -d);
+ bcnt = BITS_PER_MP_LIMB - 1 - bcnt;
+ vsize = mpn_rshift (vp, vp + i, vsize - i, bcnt);
+ }
+ }
+
+ /* GCD(U_IN, V_IN) now is U * 2**W_BCNT. */
+
+ wsize = usize + w_bcnt / BITS_PER_MP_LIMB + 1;
+ if (w->alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ wp = w->d;
+
+ MPN_ZERO (wp, w_bcnt / BITS_PER_MP_LIMB);
+
+ cy_digit = mpn_lshift (wp + w_bcnt / BITS_PER_MP_LIMB, up, usize,
+ w_bcnt % BITS_PER_MP_LIMB);
+ wsize = usize + w_bcnt / BITS_PER_MP_LIMB;
+ if (cy_digit != 0)
+ {
+ wp[wsize] = cy_digit;
+ wsize++;
+ }
+
+ w->size = wsize;
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_gcdext.c b/gnu/lib/libgmp/mpz_gcdext.c
new file mode 100644
index 0000000..183b9bd
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_gcdext.c
@@ -0,0 +1,80 @@
+/* mpz_gcdext(g, s, t, a, b) -- Set G to gcd(a, b), and S and T such that
+ g = as + bt.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+/* Botch: SLOW! */
+
+void
+#ifdef __STDC__
+mpz_gcdext (MP_INT *g, MP_INT *s, MP_INT *t, const MP_INT *a, const MP_INT *b)
+#else
+mpz_gcdext (g, s, t, a, b)
+ MP_INT *g;
+ MP_INT *s;
+ MP_INT *t;
+ const MP_INT *a;
+ const MP_INT *b;
+#endif
+{
+ MP_INT s0, s1, q, r, x, d0, d1;
+
+ mpz_init_set_ui (&s0, 1);
+ mpz_init_set_ui (&s1, 0);
+ mpz_init (&q);
+ mpz_init (&r);
+ mpz_init (&x);
+ mpz_init_set (&d0, a);
+ mpz_init_set (&d1, b);
+
+ while (d1.size != 0)
+ {
+ mpz_divmod (&q, &r, &d0, &d1);
+ mpz_set (&d0, &d1);
+ mpz_set (&d1, &r);
+
+ mpz_mul (&x, &s1, &q);
+ mpz_sub (&x, &s0, &x);
+ mpz_set (&s0, &s1);
+ mpz_set (&s1, &x);
+ }
+
+ if (t != NULL)
+ {
+ mpz_mul (&x, &s0, a);
+ mpz_sub (&x, &d0, &x);
+ if (b->size == 0)
+ t->size = 0;
+ else
+ mpz_div (t, &x, b);
+ }
+ mpz_set (s, &s0);
+ mpz_set (g, &d0);
+
+ mpz_clear (&s0);
+ mpz_clear (&s1);
+ mpz_clear (&q);
+ mpz_clear (&r);
+ mpz_clear (&x);
+ mpz_clear (&d0);
+ mpz_clear (&d1);
+}
diff --git a/gnu/lib/libgmp/mpz_get_si.c b/gnu/lib/libgmp/mpz_get_si.c
new file mode 100644
index 0000000..9cddf4b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_get_si.c
@@ -0,0 +1,40 @@
+/* mpz_get_si(integer) -- Return the least significant digit from INTEGER.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+signed long int
+#ifdef __STDC__
+mpz_get_si (const MP_INT *integer)
+#else
+mpz_get_si (integer)
+ const MP_INT *integer;
+#endif
+{
+ mp_size size = integer->size;
+
+ if (size > 0)
+ return integer->d[0] % ((mp_limb) 1 << (BITS_PER_MP_LIMB - 1));
+ else if (size < 0)
+ return -(integer->d[0] % ((mp_limb) 1 << (BITS_PER_MP_LIMB - 1)));
+ else
+ return 0;
+}
diff --git a/gnu/lib/libgmp/mpz_get_str.c b/gnu/lib/libgmp/mpz_get_str.c
new file mode 100644
index 0000000..ac5ee65
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_get_str.c
@@ -0,0 +1,39 @@
+/* mpz_get_str (string, base, mp_src) -- Convert the multiple precision
+ number MP_SRC to a string STRING of base BASE. If STRING is NULL
+ allocate space for the result. In any case, return a pointer to the
+ result. If STRING is not NULL, the caller must ensure enough space is
+ available to store the result.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+char *
+#ifdef __STDC__
+mpz_get_str (char *str, int base, const MP_INT *m)
+#else
+mpz_get_str (str, base, m)
+ char *str;
+ int base;
+ const MP_INT *m;
+#endif
+{
+ return _mpz_get_str (str, base, m);
+}
diff --git a/gnu/lib/libgmp/mpz_get_ui.c b/gnu/lib/libgmp/mpz_get_ui.c
new file mode 100644
index 0000000..118f249
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_get_ui.c
@@ -0,0 +1,36 @@
+/* mpz_get_ui(integer) -- Return the least significant digit from INTEGER.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#ifdef __STDC__
+mpz_get_ui (const MP_INT *integer)
+#else
+mpz_get_ui (integer)
+ const MP_INT *integer;
+#endif
+{
+ if (integer->size == 0)
+ return 0;
+ else
+ return integer->d[0];
+}
diff --git a/gnu/lib/libgmp/mpz_init.c b/gnu/lib/libgmp/mpz_init.c
new file mode 100644
index 0000000..5766a41
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_init.c
@@ -0,0 +1,35 @@
+/* mpz_init() -- Make a new multiple precision number with value 0.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_init (MP_INT *x)
+#else
+mpz_init (x)
+ MP_INT *x;
+#endif
+{
+ x->alloc = 1;
+ x->d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->alloc);
+ x->size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz_inp_raw.c b/gnu/lib/libgmp/mpz_inp_raw.c
new file mode 100644
index 0000000..576f4b6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_inp_raw.c
@@ -0,0 +1,72 @@
+/* mpz_inp_raw -- Input a MP_INT in raw, but endianess, and wordsize
+ independent format (as output by mpz_out_raw).
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_inp_raw (MP_INT *x, FILE *file)
+#else
+mpz_inp_raw (x, file)
+ MP_INT *x;
+ FILE *file;
+#endif
+{
+ int i;
+ mp_size s;
+ mp_size xsize;
+ mp_ptr xp;
+ unsigned int c;
+ mp_limb x_digit;
+ mp_size x_index;
+
+ xsize = 0;
+ for (i = 4 - 1; i >= 0; i--)
+ {
+ c = fgetc (file);
+ xsize = (xsize << BITS_PER_CHAR) | c;
+ }
+
+ /* ??? Sign extend xsize for non-32 bit machines? */
+
+ x_index = (ABS (xsize) + BYTES_PER_MP_LIMB - 1) / BYTES_PER_MP_LIMB - 1;
+
+ if (x->alloc < x_index)
+ _mpz_realloc (x, x_index);
+
+ xp = x->d;
+ x->size = xsize / BYTES_PER_MP_LIMB;
+ x_digit = 0;
+ for (s = ABS (xsize) - 1; s >= 0; s--)
+ {
+ i = s % BYTES_PER_MP_LIMB;
+ c = fgetc (file);
+ x_digit = (x_digit << BITS_PER_CHAR) | c;
+ if (i == 0)
+ {
+ xp[x_index--] = x_digit;
+ x_digit = 0;
+ }
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_inp_str.c b/gnu/lib/libgmp/mpz_inp_str.c
new file mode 100644
index 0000000..a775996
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_inp_str.c
@@ -0,0 +1,105 @@
+/* mpz_inp_str(dest_integer, stream, base) -- Input a number in base
+ BASE from stdio stream STREAM and store the result in DEST_INTEGER.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static int
+char_ok_for_base (c, base)
+ int c;
+ int base;
+{
+ if (isdigit (c))
+ return (unsigned) c - '0' < base;
+ if (islower (c))
+ return (unsigned) c - 'a' + 10 < base;
+ if (isupper (c))
+ return (unsigned) c - 'A' + 10 < base;
+
+ return 0;
+}
+
+void
+#ifdef __STDC__
+mpz_inp_str (MP_INT *dest, FILE *stream, int base)
+#else
+mpz_inp_str (dest, stream, base)
+ MP_INT *dest;
+ FILE *stream;
+ int base;
+#endif
+{
+ char *str;
+ size_t str_size;
+ size_t i;
+ int c;
+ int negative = 0;
+
+ str_size = 100;
+ str = (char *) (*_mp_allocate_func) (str_size);
+
+ c = getc (stream);
+ if (c == '-')
+ {
+ negative = 1;
+ c = getc (stream);
+ }
+
+ /* If BASE is 0, try to find out the base by looking at the initial
+ characters. */
+ if (base == 0)
+ {
+ base = 10;
+ if (c == '0')
+ {
+ base = 8;
+ c = getc (stream);
+ if (c == 'x' || c == 'X')
+ {
+ base = 16;
+ c = getc (stream);
+ }
+ }
+ }
+
+ for (i = 0; char_ok_for_base (c, base); i++)
+ {
+ if (i >= str_size)
+ {
+ size_t old_str_size = str_size;
+ str_size = str_size * 3 / 2;
+ str = (char *) (*_mp_reallocate_func) (str, old_str_size, str_size);
+ }
+ str[i] = c;
+ c = getc (stream);
+ }
+
+ ungetc (c, stream);
+
+ str[i] = 0;
+ _mpz_set_str (dest, str, base);
+ if (negative)
+ dest->size = -dest->size;
+
+ (*_mp_free_func) (str, str_size);
+}
diff --git a/gnu/lib/libgmp/mpz_ior.c b/gnu/lib/libgmp/mpz_ior.c
new file mode 100644
index 0000000..bf7b1c1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_ior.c
@@ -0,0 +1,242 @@
+/* mpz_ior -- Logical inclusive or.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#define min(l,o) ((l) < (o) ? (l) : (o))
+#define max(h,i) ((h) > (i) ? (h) : (i))
+
+void
+#ifdef __STDC__
+mpz_ior (MP_INT *res, const MP_INT *op1, const MP_INT *op2)
+#else
+mpz_ior (res, op1, op2)
+ MP_INT *res;
+ const MP_INT *op1;
+ const MP_INT *op2;
+#endif
+{
+ mp_srcptr op1_ptr, op2_ptr;
+ mp_size op1_size, op2_size;
+ mp_ptr res_ptr;
+ mp_size res_size;
+ mp_size i;
+
+ op1_size = op1->size;
+ op2_size = op2->size;
+
+ op1_ptr = op1->d;
+ op2_ptr = op2->d;
+ res_ptr = res->d;
+
+ if (op1_size >= 0)
+ {
+ if (op2_size >= 0)
+ {
+ if (op1_size >= op2_size)
+ {
+ if (res->alloc < op1_size)
+ {
+ _mpz_realloc (res, op1_size);
+ op1_ptr = op1->d;
+ op2_ptr = op2->d;
+ res_ptr = res->d;
+ }
+
+ if (res_ptr != op1_ptr)
+ MPN_COPY (res_ptr + op2_size, op1_ptr + op2_size,
+ op1_size - op2_size);
+ for (i = op2_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op1_size;
+ }
+ else
+ {
+ if (res->alloc < op2_size)
+ {
+ _mpz_realloc (res, op2_size);
+ op1_ptr = op1->d;
+ op2_ptr = op2->d;
+ res_ptr = res->d;
+ }
+
+ if (res_ptr != op2_ptr)
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ for (i = op1_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] | op2_ptr[i];
+ res_size = op2_size;
+ }
+
+ res->size = res_size;
+ return;
+ }
+ else /* op2_size < 0 */
+ /* Fall through to the code at the end of the function. */
+ ;
+ }
+ else
+ {
+ if (op2_size < 0)
+ {
+ mp_ptr opx;
+ mp_limb cy;
+ mp_limb one = 1;
+
+ /* Both operands are negative, so will be the result.
+ -((-OP1) | (-OP2)) = -(~(OP1 - 1) | ~(OP2 - 1)) =
+ = ~(~(OP1 - 1) | ~(OP2 - 1)) + 1 =
+ = ((OP1 - 1) & (OP2 - 1)) + 1 */
+
+ op1_size = -op1_size;
+ op2_size = -op2_size;
+
+ res_size = min (op1_size, op2_size);
+
+ /* Possible optimization: Decrease mpn_sub precision,
+ as we won't use the entire res of both. */
+ opx = (mp_ptr) alloca (op1_size * BYTES_PER_MP_LIMB);
+ op1_size += mpn_sub (opx, op1_ptr, op1_size, &one, 1);
+ op1_ptr = opx;
+
+ opx = (mp_ptr) alloca (op2_size * BYTES_PER_MP_LIMB);
+ op2_size += mpn_sub (opx, op2_ptr, op2_size, &one, 1);
+ op2_ptr = opx;
+
+ if (res->alloc < res_size)
+ {
+ _mpz_realloc (res, res_size);
+ res_ptr = res->d;
+ /* Don't re-read OP1_PTR and OP2_PTR. They point to
+ temporary space--never to the space RES->D used
+ to point to before reallocation. */
+ }
+
+ /* First loop finds the size of the result. */
+ for (i = res_size - 1; i >= 0; i--)
+ if ((op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+
+ /* Second loop computes the real result. */
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = op1_ptr[i] & op2_ptr[i];
+
+ if (res_size != 0)
+ {
+ cy = mpn_add (res_ptr, res_ptr, res_size, &one, 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ res->size = -res_size;
+ return;
+ }
+ else
+ {
+ /* We should compute -OP1 | OP2. Swap OP1 and OP2 and fall
+ through to the code that handles OP1 | -OP2. */
+ {const MP_INT *t = op1; op1 = op2; op2 = t;}
+ {mp_srcptr t = op1_ptr; op1_ptr = op2_ptr; op2_ptr = t;}
+ {mp_size t = op1_size; op1_size = op2_size; op2_size = t;}
+ }
+ }
+
+ {
+ mp_ptr opx;
+ mp_limb cy;
+ mp_limb one = 1;
+ mp_size res_alloc;
+
+ /* Operand 2 negative, so will be the result.
+ -(OP1 | (-OP2)) = -(OP1 | ~(OP2 - 1)) =
+ = ~(OP1 | ~(OP2 - 1)) + 1 =
+ = (~OP1 & (OP2 - 1)) + 1 */
+
+ op2_size = -op2_size;
+
+ res_alloc = op2_size;
+
+ opx = (mp_ptr) alloca (op2_size * BYTES_PER_MP_LIMB);
+ op2_size += mpn_sub (opx, op2_ptr, op2_size, &one, 1);
+ op2_ptr = opx;
+
+ if (res->alloc < res_alloc)
+ {
+ _mpz_realloc (res, res_alloc);
+ op1_ptr = op1->d;
+ res_ptr = res->d;
+ /* Don't re-read OP2_PTR. It points to temporary space--never
+ to the space RES->D used to point to before reallocation. */
+ }
+
+ if (op1_size >= op2_size)
+ {
+ /* We can just ignore the part of OP1 that stretches above OP2,
+ because the result limbs are zero there. */
+
+ /* First loop finds the size of the result. */
+ for (i = op2_size - 1; i >= 0; i--)
+ if ((~op1_ptr[i] & op2_ptr[i]) != 0)
+ break;
+ res_size = i + 1;
+ }
+ else
+ {
+ res_size = op2_size;
+
+ /* Copy the part of OP2 that stretches above OP1, to RES. */
+ MPN_COPY (res_ptr + op1_size, op2_ptr + op1_size,
+ op2_size - op1_size);
+ }
+
+ /* Second loop computes the real result. */
+ for (i = res_size - 1; i >= 0; i--)
+ res_ptr[i] = ~op1_ptr[i] & op2_ptr[i];
+
+ if (res_size != 0)
+ {
+ cy = mpn_add (res_ptr, res_ptr, res_size, &one, 1);
+ if (cy)
+ {
+ res_ptr[res_size] = cy;
+ res_size++;
+ }
+ }
+ else
+ {
+ res_ptr[0] = 1;
+ res_size = 1;
+ }
+
+ res->size = -res_size;
+ alloca (0);
+ return;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_iset.c b/gnu/lib/libgmp/mpz_iset.c
new file mode 100644
index 0000000..53c9d3e
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_iset.c
@@ -0,0 +1,45 @@
+/* mpz_init_set (src_integer) -- Make a new multiple precision number with
+ a value copied from SRC_INTEGER.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_init_set (MP_INT *x, const MP_INT *src)
+#else
+mpz_init_set (x, src)
+ MP_INT *x;
+ const MP_INT *src;
+#endif
+{
+ mp_size size;
+ mp_size abs_size;
+
+ size = src->size;
+ abs_size = ABS (size);
+
+ x->alloc = abs_size == 0 ? 1 : abs_size;
+ x->d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->alloc);
+
+ MPN_COPY (x->d, src->d, abs_size);
+ x->size = size;
+}
diff --git a/gnu/lib/libgmp/mpz_iset_si.c b/gnu/lib/libgmp/mpz_iset_si.c
new file mode 100644
index 0000000..66bbda1
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_iset_si.c
@@ -0,0 +1,48 @@
+/* mpz_init_set_si(val) -- Make a new multiple precision number with
+ value val.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_init_set_si (MP_INT *x, signed long int val)
+#else
+mpz_init_set_si (x, val)
+ MP_INT *x;
+ signed long int val;
+#endif
+{
+ x->alloc = 1;
+ x->d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->alloc);
+ if (val > 0)
+ {
+ x->d[0] = val;
+ x->size = 1;
+ }
+ else if (val < 0)
+ {
+ x->d[0] = -val;
+ x->size = -1;
+ }
+ else
+ x->size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz_iset_str.c b/gnu/lib/libgmp/mpz_iset_str.c
new file mode 100644
index 0000000..b110b11
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_iset_str.c
@@ -0,0 +1,42 @@
+/* mpz_init_set_str(mpz, string, base) -- Initialize MPZ and set it to the
+ value in the \0-terminated ascii string STRING in base BASE. Return 0 if
+ the string was accepted, -1 if an error occured. If BASE == 0 determine
+ the base in the C standard way, i.e. 0xhh...h means base 16, 0oo...o
+ means base 8, otherwise assume base 10.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+int
+#ifdef __STDC__
+mpz_init_set_str (MP_INT *x, const char *str, int base)
+#else
+mpz_init_set_str (x, str, base)
+ MP_INT *x;
+ const char *str;
+ int base;
+#endif
+{
+ x->alloc = 1;
+ x->d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->alloc);
+
+ return _mpz_set_str (x, str, base);
+}
diff --git a/gnu/lib/libgmp/mpz_iset_ui.c b/gnu/lib/libgmp/mpz_iset_ui.c
new file mode 100644
index 0000000..bd52640
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_iset_ui.c
@@ -0,0 +1,43 @@
+/* mpz_init_set_ui(val) -- Make a new multiple precision number with
+ value val.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_init_set_ui (MP_INT *x, unsigned long int val)
+#else
+mpz_init_set_ui (x, val)
+ MP_INT *x;
+ unsigned long int val;
+#endif
+{
+ x->alloc = 1;
+ x->d = (mp_ptr) (*_mp_allocate_func) (BYTES_PER_MP_LIMB * x->alloc);
+ if (val > 0)
+ {
+ x->d[0] = val;
+ x->size = 1;
+ }
+ else
+ x->size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz_mdiv.c b/gnu/lib/libgmp/mpz_mdiv.c
new file mode 100644
index 0000000..bb8b9de
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mdiv.c
@@ -0,0 +1,52 @@
+/* mpz_mdiv -- Mathematical DIVision and MODulo, i.e. division that rounds
+ the quotient towards -infinity.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mdiv (MP_INT *quot,
+ const MP_INT *dividend, const MP_INT *divisor)
+#else
+mpz_mdiv (quot, dividend, divisor)
+ MP_INT *quot;
+ const MP_INT *dividend;
+ const MP_INT *divisor;
+#endif
+{
+ if ((dividend->size ^ divisor->size) >= 0)
+ {
+ /* When the dividend and the divisor has same sign, this function
+ gives same result as mpz_div. */
+ mpz_div (quot, dividend, divisor);
+ }
+ else
+ {
+ MP_INT rem;
+
+ MPZ_TMP_INIT (&rem, 1 + ABS (dividend->size));
+
+ mpz_divmod (quot, &rem, dividend, divisor);
+ if (rem.size != 0)
+ mpz_sub_ui (quot, quot, 1);
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_mdiv_ui.c b/gnu/lib/libgmp/mpz_mdiv_ui.c
new file mode 100644
index 0000000..fbf127f
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mdiv_ui.c
@@ -0,0 +1,43 @@
+/* mpz_mdiv_ui -- Mathematical DIVision and MODulo, i.e. division that rounds
+ the quotient towards -infinity.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mdiv_ui (MP_INT *quot,
+ const MP_INT *dividend, unsigned long int divisor)
+#else
+mpz_mdiv_ui (quot, dividend, divisor)
+ MP_INT *quot;
+ const MP_INT *dividend;
+ unsigned long int divisor;
+#endif
+{
+ MP_INT rem;
+
+ MPZ_TMP_INIT (&rem, 1 + ABS (dividend->size));
+
+ mpz_divmod_ui (quot, &rem, dividend, divisor);
+ if (rem.size < 0)
+ mpz_sub_ui (quot, quot, 1);
+}
diff --git a/gnu/lib/libgmp/mpz_mdm.c b/gnu/lib/libgmp/mpz_mdm.c
new file mode 100644
index 0000000..0844643
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mdm.c
@@ -0,0 +1,64 @@
+/* mpz_mdivmod -- Mathematical DIVision and MODulo, i.e. division that rounds
+ the quotient towards -infinity, and with the remainder non-negative.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mdivmod (MP_INT *quot, MP_INT *rem,
+ const MP_INT *dividend, const MP_INT *divisor)
+#else
+mpz_mdivmod (quot, rem, dividend, divisor)
+ MP_INT *quot;
+ MP_INT *rem;
+ const MP_INT *dividend;
+ const MP_INT *divisor;
+#endif
+{
+ if ((dividend->size ^ divisor->size) >= 0)
+ {
+ /* When the dividend and the divisor has same sign, this function
+ gives same result as mpz_divmod. */
+ mpz_divmod (quot, rem, dividend, divisor);
+ }
+ else
+ {
+ MP_INT temp_divisor; /* N.B.: lives until function returns! */
+
+ /* We need the original value of the divisor after the quotient and
+ remainder have been preliminary calculated. We have to copy it to
+ temporary space if it's the same variable as either QUOT or REM. */
+ if (quot == divisor || rem == divisor)
+ {
+ MPZ_TMP_INIT (&temp_divisor, ABS (divisor->size));
+ mpz_set (&temp_divisor, divisor);
+ divisor = &temp_divisor;
+ }
+
+ mpz_divmod (quot, rem, dividend, divisor);
+ if (rem->size != 0)
+ {
+ mpz_sub_ui (quot, quot, 1);
+ mpz_add (rem, rem, divisor);
+ }
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_mdm_ui.c b/gnu/lib/libgmp/mpz_mdm_ui.c
new file mode 100644
index 0000000..cf41912
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mdm_ui.c
@@ -0,0 +1,58 @@
+/* mpz_mdivmod -- Mathematical DIVision and MODulo, i.e. division that rounds
+ the quotient towards -infinity, and with the remainder non-negative.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#ifdef __STDC__
+mpz_mdivmod_ui (MP_INT *quot, MP_INT *rem,
+ const MP_INT *dividend, unsigned long int divisor)
+#else
+mpz_mdivmod_ui (quot, rem, dividend, divisor)
+ MP_INT *quot;
+ MP_INT *rem;
+ const MP_INT *dividend;
+ unsigned long int divisor;
+#endif
+{
+ MP_INT temp_rem; /* N.B.: lives until function returns! */
+
+ /* If the user doesn't want the remainder to be stored in an integer
+ object, allocate a scratch variable for it. */
+ if (rem == NULL)
+ {
+ MPZ_TMP_INIT (&temp_rem, 1 + ABS (dividend->size));
+ rem = &temp_rem;
+ }
+
+ mpz_divmod_ui (quot, rem, dividend, divisor);
+
+ if (rem->size < 0)
+ {
+ mpz_sub_ui (quot, quot, 1);
+ mpz_add_ui (rem, rem, divisor);
+ }
+
+ if (rem->size == 0)
+ return 0;
+ return rem->d[0];
+}
diff --git a/gnu/lib/libgmp/mpz_mmod.c b/gnu/lib/libgmp/mpz_mmod.c
new file mode 100644
index 0000000..c1d3d3f
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mmod.c
@@ -0,0 +1,60 @@
+/* mpz_mmod -- Mathematical MODulo, i.e. with the remainder
+ non-negative.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mmod (MP_INT *rem,
+ const MP_INT *dividend, const MP_INT *divisor)
+#else
+mpz_mmod (rem, dividend, divisor)
+ MP_INT *rem;
+ const MP_INT *dividend;
+ const MP_INT *divisor;
+#endif
+{
+ if ((dividend->size ^ divisor->size) >= 0)
+ {
+ /* When the dividend and the divisor has same sign, this function
+ gives same result as mpz_mod. */
+ mpz_mod (rem, dividend, divisor);
+ }
+ else
+ {
+ MP_INT temp_divisor; /* N.B.: lives until function returns! */
+
+ /* We need the original value of the divisor after the remainder has
+ been preliminary calculated. We have to copy it to temporary
+ space if it's the same variable as REM. */
+ if (rem == divisor)
+ {
+ MPZ_TMP_INIT (&temp_divisor, ABS (divisor->size));
+ mpz_set (&temp_divisor, divisor);
+ divisor = &temp_divisor;
+ }
+
+ mpz_mod (rem, dividend, divisor);
+ if (rem->size != 0)
+ mpz_add (rem, rem, divisor);
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_mmod_ui.c b/gnu/lib/libgmp/mpz_mmod_ui.c
new file mode 100644
index 0000000..0fdbee2
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mmod_ui.c
@@ -0,0 +1,52 @@
+/* mpz_mmod -- Mathematical MODulo, i.e. with the remainder
+ non-negative.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+unsigned long int
+#ifdef __STDC__
+mpz_mmod_ui (MP_INT *rem,
+ const MP_INT *dividend, unsigned long int divisor)
+#else
+mpz_mmod_ui (rem, dividend, divisor)
+ MP_INT *rem;
+ const MP_INT *dividend;
+ unsigned long int divisor;
+#endif
+{
+ MP_INT temp_rem; /* N.B.: lives until function returns! */
+
+ if (rem == NULL)
+ {
+ MPZ_TMP_INIT (&temp_rem, 1 + ABS (dividend->size));
+ rem = &temp_rem;
+ }
+
+ mpz_mod_ui (rem, dividend, divisor);
+
+ if (rem->size < 0)
+ mpz_add_ui (rem, rem, divisor);
+
+ if (rem->size == 0)
+ return 0;
+ return rem->d[0];
+}
diff --git a/gnu/lib/libgmp/mpz_mod.c b/gnu/lib/libgmp/mpz_mod.c
new file mode 100644
index 0000000..276bee0
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mod.c
@@ -0,0 +1,36 @@
+/* mpz_mod(rem, dividend, divisor) -- Set REM to DIVIDEND mod DIVISOR.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_mod (MP_INT *rem, const MP_INT *num, const MP_INT *den)
+#else
+mpz_mod (rem, num, den)
+ MP_INT *rem;
+ const MP_INT *num;
+ const MP_INT *den;
+#endif
+
+#undef COMPUTE_QUOTIENT
+#include "mpz_dmincl.c"
diff --git a/gnu/lib/libgmp/mpz_mod_2exp.c b/gnu/lib/libgmp/mpz_mod_2exp.c
new file mode 100644
index 0000000..696acd4
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mod_2exp.c
@@ -0,0 +1,82 @@
+/* mpz_mod_2exp -- divide a MP_INT by 2**n and produce a remainder.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mod_2exp (MP_INT *res, const MP_INT *in, unsigned long int cnt)
+#else
+mpz_mod_2exp (res, in, cnt)
+ MP_INT *res;
+ const MP_INT *in;
+ unsigned long int cnt;
+#endif
+{
+ mp_size in_size = ABS (in->size);
+ mp_size res_size;
+ mp_size limb_cnt = cnt / BITS_PER_MP_LIMB;
+ mp_srcptr in_ptr = in->d;
+
+ if (in_size > limb_cnt)
+ {
+ /* The input operand is (probably) greater than 2**CNT. */
+ mp_limb x;
+
+ x = in_ptr[limb_cnt] & (((mp_limb) 1 << cnt % BITS_PER_MP_LIMB) - 1);
+ if (x != 0)
+ {
+ res_size = limb_cnt + 1;
+ if (res->alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ res->d[limb_cnt] = x;
+ }
+ else
+ {
+ mp_size i;
+
+ for (i = limb_cnt - 1; i >= 0; i--)
+ if (in_ptr[i] != 0)
+ break;
+ res_size = i + 1;
+
+ if (res->alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+ }
+ else
+ {
+ /* The input operand is smaller than 2**CNT. We perform a no-op,
+ apart from that we might need to copy IN to RES. */
+ res_size = in_size;
+ if (res->alloc < res_size)
+ _mpz_realloc (res, res_size);
+
+ limb_cnt = res_size;
+ }
+
+ if (res != in)
+ MPN_COPY (res->d, in->d, limb_cnt);
+ res->size = (in->size >= 0) ? res_size : -res_size;
+}
diff --git a/gnu/lib/libgmp/mpz_mod_ui.c b/gnu/lib/libgmp/mpz_mod_ui.c
new file mode 100644
index 0000000..35a4d7d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mod_ui.c
@@ -0,0 +1,65 @@
+/* mpz_mod_ui(rem, dividend, divisor_limb)
+ -- Set REM to DIVDEND mod DIVISOR_LIMB.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_mod_ui (MP_INT *rem, const MP_INT *dividend,
+ unsigned long int divisor_limb)
+#else
+mpz_mod_ui (rem, dividend, divisor_limb)
+ MP_INT *rem;
+ const MP_INT *dividend;
+ unsigned long int divisor_limb;
+#endif
+{
+ mp_size sign_dividend;
+ mp_size dividend_size;
+ mp_limb remainder_limb;
+
+ sign_dividend = dividend->size;
+ dividend_size = ABS (dividend->size);
+
+ if (dividend_size == 0)
+ {
+ rem->size = 0;
+ return;
+ }
+
+ /* No need for temporary allocation and copying if QUOT == DIVIDEND as
+ the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ remainder_limb = mpn_mod_1 (dividend->d, dividend_size, divisor_limb);
+
+ if (remainder_limb == 0)
+ rem->size = 0;
+ else
+ {
+ /* Store the single-limb remainder. We don't check if there's space
+ for just one limb, since no function ever makes zero space. */
+ rem->size = sign_dividend >= 0 ? 1 : -1;
+ rem->d[0] = remainder_limb;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_mul.c b/gnu/lib/libgmp/mpz_mul.c
new file mode 100644
index 0000000..7bb2b90
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mul.c
@@ -0,0 +1,114 @@
+/* mpz_mul -- Multiply two integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_mul (MP_INT *w, const MP_INT *u, const MP_INT *v)
+#else
+mpz_mul (w, u, v)
+ MP_INT *w;
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+mult (const MP_INT *u, const MP_INT *v, MP_INT *w)
+#else
+mult (u, v, w)
+ const MP_INT *u;
+ const MP_INT *v;
+ MP_INT *w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size usize = u->size;
+ mp_size vsize = v->size;
+ mp_size wsize;
+ mp_size sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me = NULL;
+ size_t free_me_size;
+
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ /* Swap U and V. */
+ {const MP_INT *t = u; u = v; v = t;}
+ {mp_size t = usize; usize = vsize; vsize = t;}
+ }
+
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->alloc < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = w->alloc;
+ }
+ else
+ (*_mp_free_func) (wp, w->alloc * BYTES_PER_MP_LIMB);
+
+ w->alloc = wsize;
+ wp = (mp_ptr) (*_mp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
+ w->d = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = (mp_ptr) alloca (usize * BYTES_PER_MP_LIMB);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = (mp_ptr) alloca (vsize * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ wsize = mpn_mul (wp, up, usize, vp, vsize);
+ w->size = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_mul_2exp.c b/gnu/lib/libgmp/mpz_mul_2exp.c
new file mode 100644
index 0000000..1a9767a
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mul_2exp.c
@@ -0,0 +1,68 @@
+/* mpz_mul_2exp -- Multiply a bignum by 2**CNT
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_mul_2exp (MP_INT *w, const MP_INT *u, unsigned long int cnt)
+#else
+mpz_mul_2exp (w, u, cnt)
+ MP_INT *w;
+ const MP_INT *u;
+ unsigned long int cnt;
+#endif
+{
+ mp_size usize = u->size;
+ mp_size abs_usize = ABS (usize);
+ mp_size wsize;
+ mp_size limb_cnt;
+ mp_ptr wp;
+ mp_limb wdigit;
+
+ if (usize == 0)
+ {
+ w->size = 0;
+ return;
+ }
+
+ limb_cnt = cnt / BITS_PER_MP_LIMB;
+ wsize = abs_usize + limb_cnt + 1;
+ if (w->alloc < wsize)
+ _mpz_realloc (w, wsize);
+ wp = w->d;
+
+ wdigit = mpn_lshift (wp + limb_cnt, u->d, abs_usize,
+ cnt % BITS_PER_MP_LIMB);
+ wsize = abs_usize + limb_cnt;
+
+ if (wdigit != 0)
+ {
+ wp[wsize] = wdigit;
+ wsize++;
+ }
+
+ /* Zero all whole digits at low end. Do it here and not before calling
+ mpn_lshift, not to loose for U == W. */
+ MPN_ZERO (wp, limb_cnt);
+
+ w->size = (usize >= 0) ? wsize : -wsize;
+}
diff --git a/gnu/lib/libgmp/mpz_mul_ui.c b/gnu/lib/libgmp/mpz_mul_ui.c
new file mode 100644
index 0000000..f35eb4b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_mul_ui.c
@@ -0,0 +1,78 @@
+/* mpz_mul_ui(product, multiplier, small_multiplicand) -- Set
+ PRODUCT to MULTIPLICATOR times SMALL_MULTIPLICAND.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_mul_ui (MP_INT *prod, const MP_INT *mult,
+ unsigned long int small_mult)
+#else
+mpz_mul_ui (prod, mult, small_mult)
+ MP_INT *prod;
+ const MP_INT *mult;
+ unsigned long int small_mult;
+#endif
+{
+ mp_size mult_size = mult->size;
+ mp_size sign_product = mult_size;
+ mp_size i;
+ mp_limb cy;
+ mp_size prod_size;
+ mp_srcptr mult_ptr;
+ mp_ptr prod_ptr;
+
+ mult_size = ABS (mult_size);
+
+ if (mult_size == 0 || small_mult == 0)
+ {
+ prod->size = 0;
+ return;
+ }
+
+ prod_size = mult_size + 1;
+ if (prod->alloc < prod_size)
+ _mpz_realloc (prod, prod_size);
+
+ mult_ptr = mult->d;
+ prod_ptr = prod->d;
+
+ cy = 0;
+ for (i = 0; i < mult_size; i++)
+ {
+ mp_limb p1, p0;
+ umul_ppmm (p1, p0, small_mult, mult_ptr[i]);
+ p0 += cy;
+ cy = p1 + (p0 < cy);
+ prod_ptr[i] = p0;
+ }
+
+ prod_size = mult_size;
+ if (cy != 0)
+ {
+ prod_ptr[mult_size] = cy;
+ prod_size++;
+ }
+
+ prod->size = sign_product > 0 ? prod_size : -prod_size;
+}
diff --git a/gnu/lib/libgmp/mpz_neg.c b/gnu/lib/libgmp/mpz_neg.c
new file mode 100644
index 0000000..560077f
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_neg.c
@@ -0,0 +1,46 @@
+/* mpz_neg(MP_INT *dst, MP_INT *src) -- Assign the negated value of SRC to DST.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_neg (MP_INT *dst, const MP_INT *src)
+#else
+mpz_neg (dst, src)
+ MP_INT *dst;
+ const MP_INT *src;
+#endif
+{
+ mp_size src_size = src->size;
+
+ if (src != dst)
+ {
+ mp_size abs_src_size = ABS (src_size);
+
+ if (dst->alloc < abs_src_size)
+ _mpz_realloc (dst, abs_src_size);
+
+ MPN_COPY (dst->d, src->d, abs_src_size);
+ }
+
+ dst->size = -src_size;
+}
diff --git a/gnu/lib/libgmp/mpz_out_raw.c b/gnu/lib/libgmp/mpz_out_raw.c
new file mode 100644
index 0000000..27d425c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_out_raw.c
@@ -0,0 +1,55 @@
+/* mpz_out_raw -- Output a MP_INT in raw, but endianess-independent format.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_out_raw (FILE *file, const MP_INT *x)
+#else
+mpz_out_raw (file, x)
+ FILE *file;
+ const MP_INT *x;
+#endif
+{
+ int i;
+ mp_size s;
+ mp_size xsize = x->size;
+ mp_srcptr xp = x->d;
+ mp_size out_size = xsize * BYTES_PER_MP_LIMB;
+
+ /* Make the size 4 bytes on all machines, to make the format portable. */
+ for (i = 4 - 1; i >= 0; i--)
+ fputc ((out_size >> (i * BITS_PER_CHAR)) % (1 << BITS_PER_CHAR), file);
+
+ /* Output from the most significant digit to the least significant digit,
+ with each digit also output in decreasing significance order. */
+ for (s = ABS (xsize) - 1; s >= 0; s--)
+ {
+ mp_limb x_digit;
+
+ x_digit = xp[s];
+ for (i = BYTES_PER_MP_LIMB - 1; i >= 0; i--)
+ fputc ((x_digit >> (i * BITS_PER_CHAR)) % (1 << BITS_PER_CHAR), file);
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_out_str.c b/gnu/lib/libgmp/mpz_out_str.c
new file mode 100644
index 0000000..8e4d08e
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_out_str.c
@@ -0,0 +1,45 @@
+/* mpz_out_str(stream, base, integer) -- Output to STREAM the multi prec.
+ integer INTEGER in base BASE.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_out_str (FILE *stream, int base, const MP_INT *x)
+#else
+mpz_out_str (stream, base, x)
+ FILE *stream;
+ int base;
+ const MP_INT *x;
+#endif
+{
+ char *str;
+ size_t str_size;
+
+ str_size = ((size_t) (ABS (x->size) * BITS_PER_MP_LIMB
+ * __mp_bases[ABS (base)].chars_per_bit_exactly)) + 3;
+ str = (char *) alloca (str_size);
+ _mpz_get_str (str, base, x);
+ fputs (str, stream);
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_perfsqr.c b/gnu/lib/libgmp/mpz_perfsqr.c
new file mode 100644
index 0000000..4f14c06
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_perfsqr.c
@@ -0,0 +1,118 @@
+/* mpz_perfect_square_p(arg) -- Return non-zero if ARG is a pefect square,
+ zero otherwise.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#if BITS_PER_MP_LIMB == 32
+static unsigned int primes[] = {3, 5, 7, 11, 13, 17, 19, 23, 29};
+static unsigned long int residue_map[] =
+{0x3, 0x13, 0x17, 0x23b, 0x161b, 0x1a317, 0x30af3, 0x5335f, 0x13d122f3};
+
+#define PP 0xC0CFD797L /* 3 x 5 x 7 x 11 x 13 x ... x 29 */
+#endif
+
+/* sq_res_0x100[x mod 0x100] == 1 iff x mod 0x100 is a quadratic residue
+ modulo 0x100. */
+static char sq_res_0x100[0x100] =
+{
+ 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+};
+
+int
+#ifdef __STDC__
+mpz_perfect_square_p (const MP_INT *a)
+#else
+mpz_perfect_square_p (a)
+ const MP_INT *a;
+#endif
+{
+ mp_limb n1, n0;
+ mp_size i;
+ mp_size asize = a->size;
+ mp_srcptr aptr = a->d;
+ mp_limb rem;
+ mp_ptr root_ptr;
+
+ /* No negative numbers are perfect squares. */
+ if (asize < 0)
+ return 0;
+
+ /* The first test excludes 55/64 (85.9%) of the perfect square candidates
+ in O(1) time. */
+ if (sq_res_0x100[aptr[0] % 0x100] == 0)
+ return 0;
+
+#if BITS_PER_MP_LIMB == 32
+ /* The second test excludes 30652543/30808063 (99.5%) of the remaining
+ perfect square candidates in O(n) time. */
+
+ /* Firstly, compute REM = A mod PP. */
+ n1 = aptr[asize - 1];
+ if (n1 >= PP)
+ {
+ n1 = 0;
+ i = asize - 1;
+ }
+ else
+ i = asize - 2;
+
+ for (; i >= 0; i--)
+ {
+ mp_limb dummy;
+
+ n0 = aptr[i];
+ udiv_qrnnd (dummy, n1, n1, n0, PP);
+ }
+ rem = n1;
+
+ /* We have A mod PP in REM. Now decide if REM is a quadratic residue
+ modulo the factors in PP. */
+ for (i = 0; i < (sizeof primes) / sizeof (int); i++)
+ {
+ unsigned int p;
+
+ p = primes[i];
+ rem %= p;
+ if ((residue_map[i] & (1L << rem)) == 0)
+ return 0;
+ }
+#endif
+
+ /* For the third and last test, we finally compute the square root,
+ to make sure we've really got a perfect square. */
+ root_ptr = (mp_ptr) alloca ((asize + 1) / 2 * BYTES_PER_MP_LIMB);
+
+ /* Iff mpn_sqrt returns zero, the square is perfect. */
+ {
+ int retval = !mpn_sqrt (root_ptr, NULL, aptr, asize);
+ alloca (0);
+ return retval;
+ }
+}
diff --git a/gnu/lib/libgmp/mpz_pow_ui.c b/gnu/lib/libgmp/mpz_pow_ui.c
new file mode 100644
index 0000000..85ba720
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_pow_ui.c
@@ -0,0 +1,110 @@
+/* mpz_pow_ui(res, base, exp) -- Set RES to BASE**EXP.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_pow_ui (MP_INT *r, const MP_INT *b, unsigned long int e)
+#else
+mpz_pow_ui (r, b, e)
+ MP_INT *r;
+ const MP_INT *b;
+ unsigned long int e;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+rpow (const MP_INT *b, signed short int e, MP_INT *r)
+#else
+rpow (b, e, r)
+ const MP_INT *b;
+ signed short int e;
+ MP_INT *r;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_ptr rp, bp, tp, xp;
+ mp_size rsize, bsize;
+ int cnt, i;
+
+ bsize = ABS (b->size);
+
+ /* Single out cases that give result == 0 or 1. These tests are here
+ to simplify the general code below, not to optimize. */
+ if (bsize == 0
+#ifdef BERKELEY_MP
+ || e < 0
+#endif
+ )
+ {
+ r->size = 0;
+ return;
+ }
+ if (e == 0)
+ {
+ r->d[0] = 1;
+ r->size = 1;
+ return;
+ }
+
+ /* Count the number of leading zero bits of the base's most
+ significant limb. */
+ count_leading_zeros (cnt, b->d[bsize - 1]);
+
+ /* Over-estimate space requirements and allocate enough space for the
+ final result in two temporary areas. The two areas are used to
+ alternately hold the input and recieve the product for mpn_mul.
+ (This scheme is used to fulfill the requirements of mpn_mul; that
+ the product space may not be the same as any of the input operands.) */
+ rsize = bsize * e - cnt * e / BITS_PER_MP_LIMB;
+
+ rp = (mp_ptr) alloca (rsize * BYTES_PER_MP_LIMB);
+ tp = (mp_ptr) alloca (rsize * BYTES_PER_MP_LIMB);
+ bp = b->d;
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+ count_leading_zeros (cnt, e);
+
+ for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ {
+ rsize = mpn_mul (tp, rp, rsize, rp, rsize);
+ xp = tp; tp = rp; rp = xp;
+
+ if ((e & ((mp_limb) 1 << i)) != 0)
+ {
+ rsize = mpn_mul (tp, rp, rsize, bp, bsize);
+ xp = tp; tp = rp; rp = xp;
+ }
+ }
+
+ /* Now then we know the exact space requirements, reallocate if
+ necessary. */
+ if (r->alloc < rsize)
+ _mpz_realloc (r, rsize);
+
+ MPN_COPY (r->d, rp, rsize);
+ r->size = (e & 1) == 0 || b->size >= 0 ? rsize : -rsize;
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_powm.c b/gnu/lib/libgmp/mpz_powm.c
new file mode 100644
index 0000000..75949ec
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_powm.c
@@ -0,0 +1,251 @@
+/* mpz_powm(res,base,exp,mod) -- Set RES to (base**exp) mod MOD.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_powm (MP_INT *res, const MP_INT *base, const MP_INT *exp,
+ const MP_INT *mod)
+#else
+mpz_powm (res, base, exp, mod)
+ MP_INT *res;
+ const MP_INT *base;
+ const MP_INT *exp;
+ const MP_INT *mod;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+pow (const MP_INT *base, const MP_INT *exp, const MP_INT *mod, MP_INT *res)
+#else
+pow (base, exp, mod, res)
+ const MP_INT *base;
+ const MP_INT *exp;
+ const MP_INT *mod;
+ MP_INT *res;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_ptr rp, ep, mp, bp;
+ mp_size esize, msize, bsize, rsize;
+ mp_size size;
+ int mod_shift_cnt;
+ int negative_result;
+ mp_limb *free_me = NULL;
+ size_t free_me_size;
+
+ esize = ABS (exp->size);
+ msize = ABS (mod->size);
+ size = 2 * msize;
+
+ rp = res->d;
+ ep = exp->d;
+
+ /* Normalize MOD (i.e. make its most significant bit set) as required by
+ mpn_div. This will make the intermediate values in the calculation
+ slightly larger, but the correct result is obtained after a final
+ reduction using the original MOD value. */
+
+ mp = (mp_ptr) alloca (msize * BYTES_PER_MP_LIMB);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize - 1]);
+ if (mod_shift_cnt != 0)
+ (void) mpn_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY (mp, mod->d, msize);
+
+ bsize = ABS (base->size);
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it. */
+
+ /* Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp = (mp_ptr) alloca ((bsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, base->d, bsize);
+ /* We don't care about the quotient, store it above the remainder,
+ at BP + MSIZE. */
+ mpn_div (bp + msize, bp, bsize, mp, msize);
+ bsize = msize;
+ while (bsize > 0 && bp[bsize - 1] == 0)
+ bsize--;
+ }
+ else
+ {
+ bp = base->d;
+ bsize = ABS (base->size);
+ }
+
+ if (res->alloc < size)
+ {
+ /* We have to allocate more space for RES. If any of the input
+ parameters are identical to RES, defer deallocation of the old
+ space. */
+
+ if (rp == ep || rp == mp || rp == bp)
+ {
+ free_me = rp;
+ free_me_size = res->alloc;
+ }
+ else
+ (*_mp_free_func) (rp, res->alloc * BYTES_PER_MP_LIMB);
+
+ rp = (mp_ptr) (*_mp_allocate_func) (size * BYTES_PER_MP_LIMB);
+ res->alloc = size;
+ res->d = rp;
+ }
+ else
+ {
+ /* Make BASE, EXP and MOD not overlap with RES. */
+ if (rp == bp)
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ bp = (mp_ptr) alloca (bsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, rp, bsize);
+ }
+ if (rp == ep)
+ {
+ /* RES and EXP are identical. Allocate temp. space for EXP. */
+ ep = (mp_ptr) alloca (esize * BYTES_PER_MP_LIMB);
+ MPN_COPY (ep, rp, esize);
+ }
+ if (rp == mp)
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD. */
+ mp = (mp_ptr) alloca (msize * BYTES_PER_MP_LIMB);
+ MPN_COPY (mp, rp, msize);
+ }
+ }
+
+ if (esize == 0)
+ {
+ rp[0] = 1;
+ res->size = 1;
+ return;
+ }
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+
+ {
+ mp_size i;
+ mp_size xsize;
+ mp_ptr dummyp = (mp_ptr) alloca ((msize + 1) * BYTES_PER_MP_LIMB);
+ mp_ptr xp = (mp_ptr) alloca (2 * (msize + 1) * BYTES_PER_MP_LIMB);
+ int c;
+ mp_limb e;
+ mp_limb carry_limb;
+
+ negative_result = (ep[0] & 1) && base->size < 0;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e <<= (c + 1); /* shift the exp bits to the left, loose msb */
+ c = BITS_PER_MP_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternatingly by XP and RP. This
+ helps us avoid block copying, which would otherwise be necessary
+ with the overlap restrictions of mpn_div. With 50% probability
+ the result after this loop will be in the area originally pointed
+ by RP (==RES->D), and with 50% probability in the area originally
+ pointed to by XP. */
+
+ for (;;)
+ {
+ while (c != 0)
+ {
+ mp_ptr tp;
+ mp_size tsize;
+
+ xsize = mpn_mul (xp, rp, rsize, rp, rsize);
+ mpn_div (dummyp, xp, xsize, mp, msize);
+
+ /* Remove any leading zero words from the result. */
+ if (xsize > msize)
+ xsize = msize;
+ while (xsize > 0 && xp[xsize - 1] == 0)
+ xsize--;
+
+ tp = rp; rp = xp; xp = tp;
+ tsize = rsize; rsize = xsize; xsize = tsize;
+
+ if ((mp_limb_signed) e < 0)
+ {
+ if (rsize > bsize)
+ xsize = mpn_mul (xp, rp, rsize, bp, bsize);
+ else
+ xsize = mpn_mul (xp, bp, bsize, rp, rsize);
+ mpn_div (dummyp, xp, xsize, mp, msize);
+
+ /* Remove any leading zero words from the result. */
+ if (xsize > msize)
+ xsize = msize;
+ while (xsize > 0 && xp[xsize - 1] == 0)
+ xsize--;
+
+ tp = rp; rp = xp; xp = tp;
+ tsize = rsize; rsize = xsize; xsize = tsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if (i < 0)
+ break;
+ e = ep[i];
+ c = BITS_PER_MP_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
+ steps. Adjust the result by reducing it with the original MOD.
+
+ Also make sure the result is put in RES->D (where it already
+ might be, see above). */
+
+ carry_limb = mpn_lshift (res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if (carry_limb != 0)
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ mpn_div (dummyp, rp, rsize, mp, msize);
+ /* Remove any leading zero words from the result. */
+ if (rsize > msize)
+ rsize = msize;
+ while (rsize > 0 && rp[rsize - 1] == 0)
+ rsize--;
+ rsize = mpn_rshift (rp, rp, rsize, mod_shift_cnt);
+ }
+
+ res->size = negative_result >= 0 ? rsize : -rsize;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_powm_ui.c b/gnu/lib/libgmp/mpz_powm_ui.c
new file mode 100644
index 0000000..3aa9b03
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_powm_ui.c
@@ -0,0 +1,219 @@
+/* mpz_powm_ui(res,base,exp,mod) -- Set RES to (base**exp) mod MOD.
+
+Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+mpz_powm_ui (MP_INT *res, const MP_INT *base, unsigned long int exp,
+ const MP_INT *mod)
+#else
+mpz_powm_ui (res, base, exp, mod)
+ MP_INT *res;
+ const MP_INT *base;
+ unsigned long int exp;
+ const MP_INT *mod;
+#endif
+{
+ mp_ptr rp, mp, bp;
+ mp_size msize, bsize, rsize;
+ mp_size size;
+ int mod_shift_cnt;
+ int negative_result;
+ mp_limb *free_me = NULL;
+ size_t free_me_size;
+
+ msize = ABS (mod->size);
+ size = 2 * msize;
+
+ rp = res->d;
+
+ /* Normalize MOD (i.e. make its most significant bit set) as required by
+ mpn_div. This will make the intermediate values in the calculation
+ slightly larger, but the correct result is obtained after a final
+ reduction using the original MOD value. */
+
+ mp = (mp_ptr) alloca (msize * BYTES_PER_MP_LIMB);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize - 1]);
+ if (mod_shift_cnt != 0)
+ (void) mpn_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY (mp, mod->d, msize);
+
+ bsize = ABS (base->size);
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it. */
+
+ /* Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp = (mp_ptr) alloca ((bsize + 1) * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, base->d, bsize);
+ /* We don't care about the quotient, store it above the remainder,
+ at BP + MSIZE. */
+ mpn_div (bp + msize, bp, bsize, mp, msize);
+ bsize = msize;
+ while (bsize > 0 && bp[bsize - 1] == 0)
+ bsize--;
+ }
+ else
+ {
+ bp = base->d;
+ bsize = ABS (base->size);
+ }
+
+ if (res->alloc < size)
+ {
+ /* We have to allocate more space for RES. If any of the input
+ parameters are identical to RES, defer deallocation of the old
+ space. */
+
+ if (rp == mp || rp == bp)
+ {
+ free_me = rp;
+ free_me_size = res->alloc;
+ }
+ else
+ (*_mp_free_func) (rp, res->alloc * BYTES_PER_MP_LIMB);
+
+ rp = (mp_ptr) (*_mp_allocate_func) (size * BYTES_PER_MP_LIMB);
+ res->alloc = size;
+ res->d = rp;
+ }
+ else
+ {
+ /* Make BASE, EXP and MOD not overlap with RES. */
+ if (rp == bp)
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ bp = (mp_ptr) alloca (bsize * BYTES_PER_MP_LIMB);
+ MPN_COPY (bp, rp, bsize);
+ }
+ if (rp == mp)
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD. */
+ mp = (mp_ptr) alloca (msize * BYTES_PER_MP_LIMB);
+ MPN_COPY (mp, rp, msize);
+ }
+ }
+
+ if (exp == 0)
+ {
+ rp[0] = 1;
+ res->size = 1;
+ return;
+ }
+
+ MPN_COPY (rp, bp, bsize);
+ rsize = bsize;
+
+ {
+ mp_size xsize;
+ mp_ptr dummyp = (mp_ptr) alloca ((msize + 1) * BYTES_PER_MP_LIMB);
+ mp_ptr xp = (mp_ptr) alloca (2 * (msize + 1) * BYTES_PER_MP_LIMB);
+ int c;
+ mp_limb e;
+ mp_limb carry_limb;
+
+ negative_result = (exp & 1) && base->size < 0;
+
+ e = exp;
+ count_leading_zeros (c, e);
+ e <<= (c + 1); /* shift the exp bits to the left, loose msb */
+ c = BITS_PER_MP_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be necessary
+ with the overlap restrictions of mpn_div. With 50% probability
+ the result after this loop will be in the area originally pointed
+ by RP (==RES->D), and with 50% probability in the area originally
+ pointed to by XP. */
+
+ while (c != 0)
+ {
+ mp_ptr tp;
+ mp_size tsize;
+
+ xsize = mpn_mul (xp, rp, rsize, rp, rsize);
+ mpn_div (dummyp, xp, xsize, mp, msize);
+
+ /* Remove any leading zero words from the result. */
+ if (xsize > msize)
+ xsize = msize;
+ while (xsize > 0 && xp[xsize - 1] == 0)
+ xsize--;
+
+ tp = rp; rp = xp; xp = tp;
+ tsize = rsize; rsize = xsize; xsize = tsize;
+
+ if ((mp_limb_signed) e < 0)
+ {
+ if (rsize > bsize)
+ xsize = mpn_mul (xp, rp, rsize, bp, bsize);
+ else
+ xsize = mpn_mul (xp, bp, bsize, rp, rsize);
+ mpn_div (dummyp, xp, xsize, mp, msize);
+
+ /* Remove any leading zero words from the result. */
+ if (xsize > msize)
+ xsize = msize;
+ while (xsize > 0 && xp[xsize - 1] == 0)
+ xsize--;
+
+ tp = rp; rp = xp; xp = tp;
+ tsize = rsize; rsize = xsize; xsize = tsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
+ steps. Adjust the result by reducing it with the original MOD.
+
+ Also make sure the result is put in RES->D (where it already
+ might be, see above). */
+
+ carry_limb = mpn_lshift (res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if (carry_limb != 0)
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ mpn_div (dummyp, rp, rsize, mp, msize);
+ /* Remove any leading zero words from the result. */
+ if (rsize > msize)
+ rsize = msize;
+ while (rsize > 0 && rp[rsize - 1] == 0)
+ rsize--;
+ rsize = mpn_rshift (rp, rp, rsize, mod_shift_cnt);
+ }
+
+ res->size = negative_result >= 0 ? rsize : -rsize;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_pprime_p.c b/gnu/lib/libgmp/mpz_pprime_p.c
new file mode 100644
index 0000000..9d08803
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_pprime_p.c
@@ -0,0 +1,108 @@
+/* mpz_probab_prime_p --
+ An implementation of the probabilistic primality test found in Knuth's
+ Seminumerical Algorithms book. If the function mpz_probab_prime_p()
+ returns 0 then n is not prime. If it returns 1, then n is 'probably'
+ prime. The probability of a false positive is (1/4)**reps, where
+ reps is the number of internal passes of the probabilistic algorithm.
+ Knuth indicates that 25 passes are reasonable.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+Contributed by John Amanatides.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+static int
+possibly_prime (n, n_minus_1, x, y, q, k)
+ MP_INT *n, *n_minus_1, *x, *y, *q;
+ int k;
+{
+ int i;
+
+ /* find random x s.t. 1 < x < n */
+ do
+ {
+ mpz_random (x, mpz_size (n));
+ mpz_mmod (x, x, n);
+ }
+ while (mpz_cmp_ui (x, 1) <= 0);
+
+ mpz_powm (y, x, q, n);
+
+ if (mpz_cmp_ui (y, 1) == 0 || mpz_cmp (y, n_minus_1) == 0)
+ return 1;
+
+ for (i = 1; i < k; i++)
+ {
+ mpz_powm_ui (y, y, 2, n);
+ if (mpz_cmp (y, n_minus_1) == 0)
+ return 1;
+ if (mpz_cmp_ui (y, 1) == 0)
+ return 0;
+ }
+ return 0;
+}
+
+int
+mpz_probab_prime_p (m, reps)
+ const MP_INT *m;
+ int reps;
+{
+ MP_INT n, n_minus_1, x, y, q;
+ int i, k, is_prime;
+
+ mpz_init (&n);
+ /* Take the absolute value of M, to handle positive and negative primes. */
+ mpz_abs (&n, m);
+
+ if (mpz_cmp_ui (&n, 3) <= 0)
+ {
+ if (mpz_cmp_ui (&n, 1) <= 0)
+ return 0; /* smallest prime is 2 */
+ else
+ return 1;
+ }
+ if ((mpz_get_ui (&n) & 1) == 0)
+ return 0; /* even */
+
+ mpz_init (&n_minus_1);
+ mpz_sub_ui (&n_minus_1, &n, 1);
+ mpz_init (&x);
+ mpz_init (&y);
+
+ /* find q and k, s.t. n = 1 + 2**k * q */
+ mpz_init_set (&q, &n_minus_1);
+ k = 0;
+ while ((mpz_get_ui (&q) & 1) == 0)
+ {
+ k++;
+ mpz_div_2exp (&q, &q, 1);
+ }
+
+ is_prime = 1;
+ for (i = 0; i < reps && is_prime; i++)
+ is_prime &= possibly_prime (&n, &n_minus_1, &x, &y, &q, k);
+
+ mpz_clear (&n_minus_1);
+ mpz_clear (&n);
+ mpz_clear (&x);
+ mpz_clear (&y);
+ mpz_clear (&q);
+ return is_prime;
+}
diff --git a/gnu/lib/libgmp/mpz_random.c b/gnu/lib/libgmp/mpz_random.c
new file mode 100644
index 0000000..c97bbff
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_random.c
@@ -0,0 +1,68 @@
+/* mpz_random -- Generate a random MP_INT of specified size.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined (hpux) || defined (__alpha__)
+/* HPUX lacks random(). DEC Alpha's random() returns a double. */
+static inline long
+urandom ()
+{
+ return mrand48 ();
+}
+#else
+long random ();
+
+static inline long
+urandom ()
+{
+ /* random() returns 31 bits, we want 32. */
+ return random() ^ (random() << 1);
+}
+#endif
+
+void
+#ifdef __STDC__
+mpz_random (MP_INT *x, mp_size size)
+#else
+mpz_random (x, size)
+ MP_INT *x;
+ mp_size size;
+#endif
+{
+ mp_size i;
+ mp_limb ran;
+
+ if (x->alloc < size)
+ _mpz_realloc (x, size);
+
+ for (i = 0; i < size; i++)
+ {
+ ran = urandom ();
+ x->d[i] = ran;
+ }
+
+ for (i = size - 1; i >= 0; i--)
+ if (x->d[i] != 0)
+ break;
+
+ x->size = i + 1;
+}
diff --git a/gnu/lib/libgmp/mpz_random2.c b/gnu/lib/libgmp/mpz_random2.c
new file mode 100644
index 0000000..6011528
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_random2.c
@@ -0,0 +1,88 @@
+/* mpz_random2 -- Generate a positive random MP_INT of specified size, with
+ long runs of consecutive ones and zeros in the binary representation.
+ Meant for testing of other MP routines.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#if defined (hpux) || defined (__alpha__)
+/* HPUX lacks random(). DEC Alpha's random() returns a double. */
+static inline long
+random ()
+{
+ return mrand48 ();
+}
+#else
+long random ();
+#endif
+
+void
+#ifdef __STDC__
+mpz_random2 (MP_INT *x, mp_size size)
+#else
+mpz_random2 (x, size)
+ MP_INT *x;
+ mp_size size;
+#endif
+{
+ mp_limb ran, cy_limb;
+ mp_ptr xp;
+ mp_size xsize, abs_size;
+ int n_bits;
+
+ abs_size = ABS (size);
+
+ if (abs_size != 0)
+ {
+ if (x->alloc < abs_size)
+ _mpz_realloc (x, abs_size);
+ xp = x->d;
+
+ xp[0] = 1;
+ for (xsize = 1;; )
+ {
+ ran = random ();
+ n_bits = (ran >> 1) % BITS_PER_MP_LIMB;
+
+ if (n_bits == 0)
+ {
+ if (xsize == abs_size)
+ break;
+ }
+ else
+ {
+ /* Would we get a too large result in mpn_lshift? */
+ if (xsize == abs_size
+ && (xp[xsize - 1] >> (BITS_PER_MP_LIMB - n_bits)) != 0)
+ break;
+
+ cy_limb = mpn_lshift (xp, xp, xsize, n_bits);
+ if (cy_limb != 0)
+ xp[xsize++] = cy_limb;
+
+ if (ran & 1)
+ xp[0] |= ((mp_limb) 1 << n_bits) - 1;
+ }
+ }
+ }
+
+ x->size = size;
+}
diff --git a/gnu/lib/libgmp/mpz_realloc.c b/gnu/lib/libgmp/mpz_realloc.c
new file mode 100644
index 0000000..11a4df3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_realloc.c
@@ -0,0 +1,50 @@
+/* _mpz_realloc -- make the MP_INT have NEW_SIZE digits allocated.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void *
+#ifdef __STDC__
+_mpz_realloc (MP_INT *m, mp_size new_size)
+#else
+_mpz_realloc (m, new_size)
+ MP_INT *m;
+ mp_size new_size;
+#endif
+{
+ /* Never allocate zero space. */
+ if (new_size == 0)
+ new_size = 1;
+
+ m->d = (mp_ptr) (*_mp_reallocate_func) (m->d, m->alloc * BYTES_PER_MP_LIMB,
+ new_size * BYTES_PER_MP_LIMB);
+ m->alloc = new_size;
+
+#if 0
+ /* This might break some code that reads the size field after
+ reallocation, in the case the reallocated destination and a
+ source argument are identical. */
+ if (ABS (m->size) > new_size)
+ m->size = 0;
+#endif
+
+ return (void *) m->d;
+}
diff --git a/gnu/lib/libgmp/mpz_set.c b/gnu/lib/libgmp/mpz_set.c
new file mode 100644
index 0000000..2441e48
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_set.c
@@ -0,0 +1,45 @@
+/* mpz_set (dest_integer, src_integer) -- Assign DEST_INTEGER from SRC_INTEGER.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_set (MP_INT *w, const MP_INT *u)
+#else
+mpz_set (w, u)
+ MP_INT *w;
+ const MP_INT *u;
+#endif
+{
+ mp_size usize;
+ mp_size abs_usize;
+
+ usize = u->size;
+ abs_usize = ABS (usize);
+
+ /* If not space for sum (and possible carry), increase space. */
+ if (w->alloc < abs_usize)
+ _mpz_realloc (w, abs_usize);
+
+ w->size = usize;
+ MPN_COPY (w->d, u->d, abs_usize);
+}
diff --git a/gnu/lib/libgmp/mpz_set_si.c b/gnu/lib/libgmp/mpz_set_si.c
new file mode 100644
index 0000000..f6d11e7
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_set_si.c
@@ -0,0 +1,47 @@
+/* mpz_set_si(integer, val) -- Assign INTEGER with a small value VAL.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_set_si (MP_INT *dest, signed long int val)
+#else
+mpz_set_si (dest, val)
+ MP_INT *dest;
+ signed long int val;
+#endif
+{
+ /* We don't check if the allocation is enough, since the rest of the
+ package ensures it's at least 1, which is what we need here. */
+ if (val > 0)
+ {
+ dest->d[0] = val;
+ dest->size = 1;
+ }
+ else if (val < 0)
+ {
+ dest->d[0] = -val;
+ dest->size = -1;
+ }
+ else
+ dest->size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz_set_str.c b/gnu/lib/libgmp/mpz_set_str.c
new file mode 100644
index 0000000..2596d8b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_set_str.c
@@ -0,0 +1,41 @@
+/* mpz_set_str(mp_dest, string, base) -- Convert the \0-terminated
+ string STRING in base BASE to multiple precision integer in
+ MP_DEST. Allow white space in the string. If BASE == 0 determine
+ the base in the C standard way, i.e. 0xhh...h means base 16,
+ 0oo...o means base 8, otherwise assume base 10.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+int
+#ifdef __STDC__
+mpz_set_str (MP_INT *x, const char *str, int base)
+#else
+mpz_set_str (x, str, base)
+ MP_INT *x;
+ const char *str;
+ int base;
+#endif
+{
+ /* Go via _mpz_set_str, as that can be used by BSD compatible functions. */
+ return _mpz_set_str (x, str, base);
+}
diff --git a/gnu/lib/libgmp/mpz_set_ui.c b/gnu/lib/libgmp/mpz_set_ui.c
new file mode 100644
index 0000000..c2e06c9
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_set_ui.c
@@ -0,0 +1,42 @@
+/* mpz_set_ui(integer, val) -- Assign INTEGER with a small value VAL.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_set_ui (MP_INT *dest, unsigned long int val)
+#else
+mpz_set_ui (dest, val)
+ MP_INT *dest;
+ unsigned long int val;
+#endif
+{
+ /* We don't check if the allocation is enough, since the rest of the
+ package ensures it's at least 1, which is what we need here. */
+ if (val > 0)
+ {
+ dest->d[0] = val;
+ dest->size = 1;
+ }
+ else
+ dest->size = 0;
+}
diff --git a/gnu/lib/libgmp/mpz_size.c b/gnu/lib/libgmp/mpz_size.c
new file mode 100644
index 0000000..8b9ff91
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_size.c
@@ -0,0 +1,34 @@
+/* mpz_size(x) -- return the number of lims currently used by the
+ value of integer X.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+size_t
+#ifdef __STDC__
+mpz_size (const MP_INT *x)
+#else
+mpz_size (x)
+ const MP_INT *x;
+#endif
+{
+ return ABS (x->size);
+}
diff --git a/gnu/lib/libgmp/mpz_sizeinb.c b/gnu/lib/libgmp/mpz_sizeinb.c
new file mode 100644
index 0000000..75a0108
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_sizeinb.c
@@ -0,0 +1,59 @@
+/* mpz_sizeinbase(x, base) -- return an approximation to the number of
+ character the integer X would have printed in base BASE. The
+ approximation is never too small.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+size_t
+#ifdef __STDC__
+mpz_sizeinbase (const MP_INT *x, int base)
+#else
+mpz_sizeinbase (x, base)
+ const MP_INT *x;
+ int base;
+#endif
+{
+ mp_size size = ABS (x->size);
+ int lb_base, cnt;
+ size_t totbits;
+
+ /* Special case for X == 0. */
+ if (size == 0)
+ return 1;
+
+ /* Calculate the total number of significant bits of X. */
+ count_leading_zeros (cnt, x->d[size - 1]);
+ totbits = size * BITS_PER_MP_LIMB - cnt;
+
+ if ((base & (base - 1)) == 0)
+ {
+ /* Special case for powers of 2, giving exact result. */
+
+ count_leading_zeros (lb_base, base);
+ lb_base = BITS_PER_MP_LIMB - lb_base - 1;
+
+ return (totbits + lb_base - 1) / lb_base;
+ }
+ else
+ return (size_t) (totbits * __mp_bases[base].chars_per_bit_exactly) + 1;
+}
diff --git a/gnu/lib/libgmp/mpz_sqrt.c b/gnu/lib/libgmp/mpz_sqrt.c
new file mode 100644
index 0000000..38408b8
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_sqrt.c
@@ -0,0 +1,87 @@
+/* mpz_sqrt(root, u) -- Set ROOT to floor(sqrt(U)).
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This code is just correct if "unsigned char" has at least 8 bits. It
+ doesn't help to use CHAR_BIT from limits.h, as the real problem is
+ the static arrays. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_sqrt (MP_INT *root, const MP_INT *op)
+#else
+mpz_sqrt (root, op)
+ MP_INT *root;
+ const MP_INT *op;
+#endif
+{
+ mp_size op_size, root_size;
+ mp_ptr root_ptr, op_ptr;
+ mp_ptr free_me = NULL;
+ mp_size free_me_size;
+
+ op_size = op->size;
+ if (op_size < 0)
+ op_size = 1 / op_size > 0; /* Divide by zero for negative OP. */
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+
+ root_ptr = root->d;
+ op_ptr = op->d;
+
+ if (root->alloc < root_size)
+ {
+ if (root_ptr == op_ptr)
+ {
+ free_me = root_ptr;
+ free_me_size = root->alloc;
+ }
+ else
+ (*_mp_free_func) (root_ptr, root->alloc * BYTES_PER_MP_LIMB);
+
+ root->alloc = root_size;
+ root_ptr = (mp_ptr) (*_mp_allocate_func) (root_size * BYTES_PER_MP_LIMB);
+ root->d = root_ptr;
+ }
+ else
+ {
+ /* Make OP not overlap with ROOT. */
+ if (root_ptr == op_ptr)
+ {
+ /* ROOT and OP are identical. Allocate temporary space for OP. */
+ op_ptr = (mp_ptr) alloca (op_size * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. Hack: Avoid temporary variable
+ by using ROOT_PTR. */
+ MPN_COPY (op_ptr, root_ptr, op_size);
+ }
+ }
+
+ mpn_sqrt (root_ptr, NULL, op_ptr, op_size);
+
+ root->size = root_size;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_sqrtrem.c b/gnu/lib/libgmp/mpz_sqrtrem.c
new file mode 100644
index 0000000..c846c95
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_sqrtrem.c
@@ -0,0 +1,105 @@
+/* mpz_sqrtrem(root,rem,x) -- Set ROOT to floor(sqrt(X)) and REM
+ to the remainder, i.e. X - ROOT**2.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_sqrtrem (MP_INT *root, MP_INT *rem, const MP_INT *op)
+#else
+mpz_sqrtrem (root, rem, op)
+ MP_INT *root;
+ MP_INT *rem;
+ const MP_INT *op;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+msqrt (const MP_INT *op, MP_INT *root, MP_INT *rem)
+#else
+msqrt (op, root, rem)
+ const MP_INT *op;
+ MP_INT *root;
+ MP_INT *rem;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_size op_size, root_size, rem_size;
+ mp_ptr root_ptr, op_ptr;
+ mp_ptr free_me = NULL;
+ mp_size free_me_size;
+
+ op_size = op->size;
+ if (op_size < 0)
+ op_size = 1 / (op_size > 0); /* Divide by zero for negative OP. */
+
+ if (rem->alloc < op_size)
+ _mpz_realloc (rem, op_size);
+
+ /* The size of the root is accurate after this simple calculation. */
+ root_size = (op_size + 1) / 2;
+
+ root_ptr = root->d;
+ op_ptr = op->d;
+
+ if (root->alloc < root_size)
+ {
+ if (root_ptr == op_ptr)
+ {
+ free_me = root_ptr;
+ free_me_size = root->alloc;
+ }
+ else
+ (*_mp_free_func) (root_ptr, root->alloc * BYTES_PER_MP_LIMB);
+
+ root->alloc = root_size;
+ root_ptr = (mp_ptr) (*_mp_allocate_func) (root_size * BYTES_PER_MP_LIMB);
+ root->d = root_ptr;
+ }
+ else
+ {
+ /* Make OP not overlap with ROOT. */
+ if (root_ptr == op_ptr)
+ {
+ /* ROOT and OP are identical. Allocate temporary space for OP. */
+ op_ptr = (mp_ptr) alloca (op_size * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. Hack: Avoid temporary variable
+ by using ROOT_PTR. */
+ MPN_COPY (op_ptr, root_ptr, op_size);
+ }
+ }
+
+ rem_size = mpn_sqrt (root_ptr, rem->d, op_ptr, op_size);
+
+ root->size = root_size;
+
+ /* Write remainder size last, to enable us to define this function to
+ give only the square root remainder, if the user calles if with
+ ROOT == REM. */
+ rem->size = rem_size;
+
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
diff --git a/gnu/lib/libgmp/mpz_sub.c b/gnu/lib/libgmp/mpz_sub.c
new file mode 100644
index 0000000..f75f06c
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_sub.c
@@ -0,0 +1,117 @@
+/* mpz_sub -- Subtract two integers.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+#ifndef BERKELEY_MP
+void
+#ifdef __STDC__
+mpz_sub (MP_INT *w, const MP_INT *u, const MP_INT *v)
+#else
+mpz_sub (w, u, v)
+ MP_INT *w;
+ const MP_INT *u;
+ const MP_INT *v;
+#endif
+#else /* BERKELEY_MP */
+void
+#ifdef __STDC__
+msub (const MP_INT *u, const MP_INT *v, MP_INT *w)
+#else
+msub (u, v, w)
+ const MP_INT *u;
+ const MP_INT *v;
+ MP_INT *w;
+#endif
+#endif /* BERKELEY_MP */
+{
+ mp_srcptr up, vp;
+ mp_ptr wp;
+ mp_size usize, vsize, wsize;
+ mp_size abs_usize;
+ mp_size abs_vsize;
+
+ usize = u->size;
+ vsize = -v->size; /* The "-" makes the difference from mpz_add */
+ abs_usize = ABS (usize);
+ abs_vsize = ABS (vsize);
+
+ if (abs_usize < abs_vsize)
+ {
+ /* Swap U and V. */
+ {const MP_INT *t = u; u = v; v = t;}
+ {mp_size t = usize; usize = vsize; vsize = t;}
+ {mp_size t = abs_usize; abs_usize = abs_vsize; abs_vsize = t;}
+ }
+
+ /* True: abs(USIZE) >= abs(VSIZE) */
+
+ /* If not space for sum (and possible carry), increase space. */
+ wsize = abs_usize + 1;
+ if (w->alloc < wsize)
+ _mpz_realloc (w, wsize);
+
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ if (usize >= 0)
+ {
+ if (vsize >= 0)
+ {
+ wsize = mpn_add (wp, up, abs_usize, vp, abs_vsize);
+ if (wsize != 0)
+ wp[abs_usize] = 1;
+ wsize = wsize + abs_usize;
+ }
+ else
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_usize == abs_vsize && mpn_cmp (up, vp, abs_usize) < 0)
+ wsize = -(abs_usize + mpn_sub (wp, vp, abs_usize, up, abs_usize));
+ else
+ wsize = abs_usize + mpn_sub (wp, up, abs_usize, vp, abs_vsize);
+ }
+ }
+ else
+ {
+ if (vsize >= 0)
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_usize == abs_vsize && mpn_cmp (up, vp, abs_usize) < 0)
+ wsize = abs_usize + mpn_sub (wp, vp, abs_usize, up, abs_usize);
+ else
+ wsize = -(abs_usize + mpn_sub (wp, up, abs_usize, vp, abs_vsize));
+ }
+ else
+ {
+ wsize = mpn_add (wp, up, abs_usize, vp, abs_vsize);
+ if (wsize != 0)
+ wp[abs_usize] = 1;
+ wsize = -(wsize + abs_usize);
+ }
+ }
+
+ w->size = wsize;
+}
diff --git a/gnu/lib/libgmp/mpz_sub_ui.c b/gnu/lib/libgmp/mpz_sub_ui.c
new file mode 100644
index 0000000..cd9a04b
--- /dev/null
+++ b/gnu/lib/libgmp/mpz_sub_ui.c
@@ -0,0 +1,84 @@
+/* mpz_sub_ui -- Subtract an unsigned one-word integer from an MP_INT.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "gmp.h"
+#include "gmp-impl.h"
+
+void
+#ifdef __STDC__
+mpz_sub_ui (MP_INT *dif, const MP_INT *min, mp_limb sub)
+#else
+mpz_sub_ui (dif, min, sub)
+ MP_INT *dif;
+ const MP_INT *min;
+ mp_limb sub;
+#endif
+{
+ mp_srcptr minp;
+ mp_ptr difp;
+ mp_size minsize, difsize;
+ mp_size abs_minsize;
+
+ minsize = min->size;
+ abs_minsize = ABS (minsize);
+
+ /* If not space for SUM (and possible carry), increase space. */
+ difsize = abs_minsize + 1;
+ if (dif->alloc < difsize)
+ _mpz_realloc (dif, difsize);
+
+ /* These must be after realloc (ADD1 may be the same as SUM). */
+ minp = min->d;
+ difp = dif->d;
+
+ if (sub == 0)
+ {
+ MPN_COPY (difp, minp, abs_minsize);
+ dif->size = minsize;
+ return;
+ }
+ if (abs_minsize == 0)
+ {
+ difp[0] = sub;
+ dif->size = -1;
+ return;
+ }
+
+ if (minsize < 0)
+ {
+ difsize = mpn_add (difp, minp, abs_minsize, &sub, 1);
+ if (difsize != 0)
+ difp[abs_minsize] = 1;
+ difsize = -(difsize + abs_minsize);
+ }
+ else
+ {
+ /* The signs are different. Need exact comparision to determine
+ which operand to subtract from which. */
+ if (abs_minsize == 1 && minp[0] < sub)
+ difsize = -(abs_minsize
+ + mpn_sub (difp, &sub, 1, minp, 1));
+ else
+ difsize = (abs_minsize
+ + mpn_sub (difp, minp, abs_minsize, &sub, 1));
+ }
+
+ dif->size = difsize;
+}
diff --git a/gnu/lib/libgmp/mtox.c b/gnu/lib/libgmp/mtox.c
new file mode 100644
index 0000000..22708e5
--- /dev/null
+++ b/gnu/lib/libgmp/mtox.c
@@ -0,0 +1,37 @@
+/* mtox -- Convert OPERAND to hexadecimal and return a malloc'ed string
+ with the result of the conversion.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+char *
+#ifdef __STDC__
+mtox (const MINT *operand)
+#else
+mtox (operand)
+ const MINT *operand;
+#endif
+{
+ /* Call MP_GET_STR with a NULL pointer as string argument, so that it
+ allocates space for the result. */
+ return _mpz_get_str ((char *) 0, 16, operand);
+}
diff --git a/gnu/lib/libgmp/sdiv.c b/gnu/lib/libgmp/sdiv.c
new file mode 100644
index 0000000..ab83dcd
--- /dev/null
+++ b/gnu/lib/libgmp/sdiv.c
@@ -0,0 +1,76 @@
+/* sdiv -- Divide a MINT by a short integer. Produce a MINT quotient
+ and a short remainder.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+
+void
+#ifdef __STDC__
+sdiv (const MINT *dividend, signed short int divisor_short, MINT *quot, short *rem_ptr)
+#else
+sdiv (dividend, divisor_short, quot, rem_ptr)
+ const MINT *dividend;
+ short int divisor_short;
+ MINT *quot;
+ short *rem_ptr;
+#endif
+{
+ mp_size sign_dividend;
+ signed long int sign_divisor;
+ mp_size dividend_size, quot_size;
+ mp_ptr dividend_ptr, quot_ptr;
+ mp_limb divisor_limb;
+ mp_limb remainder_limb;
+
+ sign_dividend = dividend->size;
+ dividend_size = ABS (dividend->size);
+
+ if (dividend_size == 0)
+ {
+ quot->size = 0;
+ *rem_ptr = 0;
+ return;
+ }
+
+ sign_divisor = divisor_short;
+ divisor_limb = ABS (divisor_short);
+
+ /* No need for temporary allocation and copying even if QUOT == DIVIDEND
+ as the divisor is just one limb, and thus no intermediate remainders
+ need to be stored. */
+
+ if (quot->alloc < dividend_size)
+ _mpz_realloc (quot, dividend_size);
+
+ quot_ptr = quot->d;
+ dividend_ptr = dividend->d;
+
+ remainder_limb = mpn_divmod_1 (quot_ptr,
+ dividend_ptr, dividend_size, divisor_limb);
+
+ *rem_ptr = sign_dividend >= 0 ? remainder_limb : -remainder_limb;
+ /* The quotient is DIVIDEND_SIZE limbs, but the most significant
+ might be zero. Set QUOT_SIZE properly. */
+ quot_size = dividend_size - (quot_ptr[dividend_size - 1] == 0);
+ quot->size = (sign_divisor ^ sign_dividend) >= 0 ? quot_size : -quot_size;
+}
diff --git a/gnu/lib/libgmp/stack-alloc.c b/gnu/lib/libgmp/stack-alloc.c
new file mode 100644
index 0000000..d9619f6
--- /dev/null
+++ b/gnu/lib/libgmp/stack-alloc.c
@@ -0,0 +1,108 @@
+/* Stack allocation routines. This is intended for machines without support
+ for the `alloca' function.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#include "stack-alloc.h"
+
+typedef struct tmp_stack tmp_stack;
+
+void *malloc ();
+static unsigned long max_total_allocation = 0;
+static unsigned long current_total_allocation = 0;
+
+static tmp_stack xxx = {&xxx, &xxx, 0};
+static tmp_stack *current = &xxx;
+
+/* Allocate a block of exactly <size> bytes. This should only be called
+ through the TMP_ALLOC macro, which takes care of rounding/alignment. */
+void *
+__tmp_alloc (size)
+ unsigned long size;
+{
+ void *this;
+
+ if (size > (char *) current->end - (char *) current->alloc_point)
+ {
+ void *chunk;
+ tmp_stack *header;
+ unsigned long chunk_size;
+ unsigned long now;
+
+ /* Allocate a chunk that makes the total current allocation somewhat
+ larger than the maximum allocation ever. If size is very large, we
+ allocate that much. */
+
+ now = current_total_allocation + size;
+ if (now > max_total_allocation)
+ {
+ /* We need more temporary memory than ever before. Increase
+ for future needs. */
+ now = now * 3 / 2;
+ chunk_size = now - current_total_allocation + sizeof (tmp_stack);
+ current_total_allocation = now;
+ max_total_allocation = current_total_allocation;
+ }
+ else
+ {
+ chunk_size = max_total_allocation - current_total_allocation + sizeof (tmp_stack);
+ current_total_allocation = max_total_allocation;
+ }
+
+ chunk = malloc (chunk_size);
+ header = chunk;
+ header->end = (char *) chunk + chunk_size;
+ header->alloc_point = (char *) chunk + sizeof (tmp_stack);
+ header->prev = current;
+ current = header;
+ }
+
+ this = current->alloc_point;
+ current->alloc_point = (char *) this + size;
+ return this;
+}
+
+/* Typically called at function entry. <mark> is assigned so that __tmp_free
+ can later be used to reclaim all subsecuently allocated storage. */
+void
+__tmp_mark (mark)
+ tmp_marker *mark;
+{
+ mark->which_chunk = current;
+ mark->alloc_point = current->alloc_point;
+}
+
+/* Free everything allocated since <mark> was assigned by __tmp_mark */
+void
+__tmp_free (mark)
+ tmp_marker *mark;
+{
+ while (mark->which_chunk != current)
+ {
+ tmp_stack *tmp;
+
+ tmp = current;
+ current = tmp->prev;
+ current_total_allocation -= (((char *) (tmp->end) - (char *) tmp)
+ - sizeof (tmp_stack));
+ free (tmp);
+ }
+ current->alloc_point = mark->alloc_point;
+}
diff --git a/gnu/lib/libgmp/stack-alloc.h b/gnu/lib/libgmp/stack-alloc.h
new file mode 100644
index 0000000..a84eeff
--- /dev/null
+++ b/gnu/lib/libgmp/stack-alloc.h
@@ -0,0 +1,56 @@
+/* Stack allocation routines. This is intended for machines without support
+ for the `alloca' function.
+
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+struct tmp_stack
+{
+ void *end;
+ void *alloc_point;
+ struct tmp_stack *prev;
+};
+
+struct tmp_marker
+{
+ struct tmp_stack *which_chunk;
+ void *alloc_point;
+};
+
+typedef struct tmp_marker tmp_marker;
+
+#if __STDC__
+void *__tmp_alloc (unsigned long);
+void __tmp_mark (tmp_marker *);
+void __tmp_free (tmp_marker *);
+#else
+void *__tmp_alloc ();
+void __tmp_mark ();
+void __tmp_free ();
+#endif
+
+#ifndef __TMP_ALIGN
+#define __TMP_ALIGN 8
+#endif
+
+#define TMP_DECL(marker) tmp_marker marker
+#define TMP_ALLOC(size) \
+ __tmp_alloc (((unsigned long) (size) + __TMP_ALIGN - 1) & -__TMP_ALIGN)
+#define TMP_MARK(marker) __tmp_mark (&marker)
+#define TMP_FREE(marker) __tmp_free (&marker)
diff --git a/gnu/lib/libgmp/tests/Makefile b/gnu/lib/libgmp/tests/Makefile
new file mode 100644
index 0000000..06a6749
--- /dev/null
+++ b/gnu/lib/libgmp/tests/Makefile
@@ -0,0 +1,66 @@
+# Makefile for tests for GNU MP
+
+# Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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.
+
+# You should have received a copy of the GNU General Public License
+# along with the GNU MP Library; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+.PATH: ${.CURDIR}/.. ${.OBJDIR} ${.OBJDIR}/../libgmp
+
+CC = gcc
+
+TEST_LIBS = -lgmp
+OPT = -O -g
+CFLAGS = -I${.CURDIR} -I${.CURDIR}/.. -I${.OBJDIR}/.. -I${.CURDIR}/../libgmp -I${.OBJDIR}/../libgmp $(OPT)
+
+TEST_SRCS = tst-mul.c tst-dm.c tst-dm_ui.c tst-mdm.c tst-mdm_ui.c tst-gcd.c \
+ tst-sqrtrem.c tst-convert.c
+TEST_OBJS = tst-mul.o tst-dm.o tst-dm_ui.o tst-mdm.o tst-mdm_ui.o tst-gcd.o \
+ tst-sqrtrem.o tst-convert.o
+TESTS = tst-mul tst-dm tst-dm_ui tst-mdm tst-mdm_ui tst-gcd \
+ tst-sqrtrem tst-convert
+
+tests: $(TESTS)
+ for i in $(TESTS); do echo $$i; ./$$i; done
+
+tst-mul: tst-mul.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-dm: tst-dm.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-dm_ui: tst-dm_ui.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-mdm: tst-mdm.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-mdm_ui: tst-mdm_ui.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-gcd: tst-gcd.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-sqrtrem: tst-sqrtrem.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-convert: tst-convert.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+
+$(TEST_PREFIX)clean:
+ rm -f $(TESTS) $(TEST_OBJS) core
+
+tst-convert.o : tst-convert.c gmp.h urandom.h
+tst-dm.o : tst-dm.c gmp.h urandom.h
+tst-dm_ui.o : tst-dm_ui.c gmp.h urandom.h
+tst-gcd.o : tst-gcd.c gmp.h urandom.h
+tst-mdm.o : tst-mdm.c gmp.h urandom.h
+tst-mdm_ui.o : tst-mdm_ui.c gmp.h urandom.h
+tst-mul.o : tst-mul.c gmp.h gmp-impl.h gmp-mparam.h longlong.h urandom.h
+tst-sqrtrem.o : tst-sqrtrem.c gmp.h urandom.h
diff --git a/gnu/lib/libgmp/tests/Makefile.GNU b/gnu/lib/libgmp/tests/Makefile.GNU
new file mode 100644
index 0000000..aa18015
--- /dev/null
+++ b/gnu/lib/libgmp/tests/Makefile.GNU
@@ -0,0 +1,64 @@
+# Makefile for tests for GNU MP
+
+# Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+# This file is part of the GNU MP Library.
+
+# The GNU MP 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 MP 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.
+
+# You should have received a copy of the GNU General Public License
+# along with the GNU MP Library; see the file COPYING. If not, write to
+# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CC = gcc
+
+TEST_LIBS = ../libgmp.a
+OPT = -O -g
+CFLAGS = -I. -I.. $(OPT)
+
+TEST_SRCS = tst-mul.c tst-dm.c tst-dm_ui.c tst-mdm.c tst-mdm_ui.c tst-gcd.c \
+ tst-sqrtrem.c tst-convert.c
+TEST_OBJS = tst-mul.o tst-dm.o tst-dm_ui.o tst-mdm.o tst-mdm_ui.o tst-gcd.o \
+ tst-sqrtrem.o tst-convert.o
+TESTS = tst-mul tst-dm tst-dm_ui tst-mdm tst-mdm_ui tst-gcd \
+ tst-sqrtrem tst-convert
+
+tests: $(TESTS)
+ for i in $(TESTS); do echo $$i; ./$$i; done
+
+tst-mul: tst-mul.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-dm: tst-dm.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-dm_ui: tst-dm_ui.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-mdm: tst-mdm.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-mdm_ui: tst-mdm_ui.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-gcd: tst-gcd.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-sqrtrem: tst-sqrtrem.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+tst-convert: tst-convert.o $(TEST_LIBS)
+ $(CC) $(CFLAGS) -o $@ $@.o $(TEST_LIBS)
+
+$(TEST_PREFIX)clean:
+ rm -f $(TESTS) $(TEST_OBJS) core
+
+tst-convert.o : tst-convert.c ../gmp.h urandom.h
+tst-dm.o : tst-dm.c ../gmp.h urandom.h
+tst-dm_ui.o : tst-dm_ui.c ../gmp.h urandom.h
+tst-gcd.o : tst-gcd.c ../gmp.h urandom.h
+tst-mdm.o : tst-mdm.c ../gmp.h urandom.h
+tst-mdm_ui.o : tst-mdm_ui.c ../gmp.h urandom.h
+tst-mul.o : tst-mul.c ../gmp.h ../gmp-impl.h ../gmp-mparam.h ../longlong.h urandom.h
+tst-sqrtrem.o : tst-sqrtrem.c ../gmp.h urandom.h
diff --git a/gnu/lib/libgmp/tests/tst-convert.c b/gnu/lib/libgmp/tests/tst-convert.c
new file mode 100644
index 0000000..bbc0dab
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-convert.c
@@ -0,0 +1,80 @@
+/* Test mpz_add, mpz_cmp, mpz_cmp_ui, mpz_gcd, mpz_gcdext, mpz_get_str,
+ mpz_mod, mpz_mul, mpz_set_str.
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ mp_size size;
+ int i;
+ int reps = 100000;
+ char *str;
+ int base;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&op1, size);
+ base = urandom () % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ str = mpz_get_str ((char *) 0, base, &op1);
+ mpz_set_str (&op2, str, base);
+ free (str);
+
+ if (mpz_cmp (&op1, &op2))
+ {
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (&op1, -16);
+ fprintf (stderr, "base = %d\n", base);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-dm.c b/gnu/lib/libgmp/tests/tst-dm.c
new file mode 100644
index 0000000..92c4194
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-dm.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_div, mpz_divmod, mpz_mod,
+ mpz_mul.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT dividend, divisor;
+ MP_INT quotient, remainder;
+ MP_INT quotient2, remainder2;
+ MP_INT temp;
+ mp_size dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&dividend);
+ mpz_init (&divisor);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+ mpz_init (&quotient2);
+ mpz_init (&remainder2);
+ mpz_init (&temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&divisor, divisor_size);
+ if (mpz_cmp_ui (&divisor, 0) == 0)
+ continue;
+
+ mpz_divmod (&quotient, &remainder, &dividend, &divisor);
+ mpz_div (&quotient2, &dividend, &divisor);
+ mpz_mod (&remainder2, &dividend, &divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (&quotient, &quotient2) != 0)
+ dump_abort (&dividend, &divisor);
+ if (mpz_cmp (&remainder, &remainder2) != 0)
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (&quotient, 0) != 0)
+ if ((mpz_cmp_ui (&quotient, 0) < 0)
+ != ((mpz_cmp_ui (&dividend, 0) ^ mpz_cmp_ui (&divisor, 0)) < 0))
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (&remainder, 0) != 0)
+ if ((mpz_cmp_ui (&remainder, 0) < 0) != (mpz_cmp_ui (&dividend, 0) < 0))
+ dump_abort (&dividend, &divisor);
+
+ mpz_mul (&temp, &quotient, &divisor);
+ mpz_add (&temp, &temp, &remainder);
+ if (mpz_cmp (&temp, &dividend) != 0)
+ dump_abort (&dividend, &divisor);
+
+ mpz_abs (&temp, &divisor);
+ mpz_abs (&remainder, &remainder);
+ if (mpz_cmp (&remainder, &temp) >= 0)
+ dump_abort (&dividend, &divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-dm_ui.c b/gnu/lib/libgmp/tests/tst-dm_ui.c
new file mode 100644
index 0000000..9f69841
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-dm_ui.c
@@ -0,0 +1,116 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_div, mpz_div_ui,
+ mpz_divmod, mpz_divmod_ui, mpz_mod, mpz_mod_ui, mpz_mul, mpz_mul_ui.
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT dividend;
+ MP_INT quotient, remainder;
+ MP_INT quotient2, remainder2;
+ MP_INT temp;
+ mp_size dividend_size;
+ mp_limb divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&dividend);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+ mpz_init (&quotient2);
+ mpz_init (&remainder2);
+ mpz_init (&temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_divmod_ui (&quotient, &remainder, &dividend, divisor);
+ mpz_div_ui (&quotient2, &dividend, divisor);
+ mpz_mod_ui (&remainder2, &dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (&quotient, &quotient2) != 0)
+ dump_abort (&dividend, divisor);
+ if (mpz_cmp (&remainder, &remainder2) != 0)
+ dump_abort (&dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (&quotient, 0) != 0)
+ if ((mpz_cmp_ui (&quotient, 0) < 0)
+ != (mpz_cmp_ui (&dividend, 0) < 0))
+ dump_abort (&dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (&remainder, 0) != 0)
+ if ((mpz_cmp_ui (&remainder, 0) < 0) != (mpz_cmp_ui (&dividend, 0) < 0))
+ dump_abort (&dividend, divisor);
+
+ mpz_mul_ui (&temp, &quotient, divisor);
+ mpz_add (&temp, &temp, &remainder);
+ if (mpz_cmp (&temp, &dividend) != 0)
+ dump_abort (&dividend, divisor);
+
+ mpz_abs (&remainder, &remainder);
+ if (mpz_cmp_ui (&remainder, divisor) >= 0)
+ dump_abort (&dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend;
+ mp_limb divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-gcd.c b/gnu/lib/libgmp/tests/tst-gcd.c
new file mode 100644
index 0000000..166aa56
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-gcd.c
@@ -0,0 +1,131 @@
+/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_mod, mpz_add, mpz_cmp,
+ mpz_cmp_ui. mpz_init_set, mpz_set, mpz_clear.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void mpz_refgcd (), debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ MP_INT refgcd, gcd, s, t;
+ MP_INT temp1, temp2;
+ mp_size op1_size, op2_size;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+ mpz_init (&refgcd);
+ mpz_init (&gcd);
+ mpz_init (&temp1);
+ mpz_init (&temp2);
+ mpz_init (&s);
+ mpz_init (&t);
+
+ for (i = 0; i < reps; i++)
+ {
+ op1_size = urandom () % SIZE;
+ op2_size = urandom () % SIZE;
+
+ mpz_random2 (&op1, op1_size);
+ mpz_random2 (&op2, op2_size);
+
+ mpz_refgcd (&refgcd, &op1, &op2);
+
+ mpz_gcd (&gcd, &op1, &op2);
+ if (mpz_cmp (&refgcd, &gcd))
+ dump_abort (&op1, &op2);
+
+ mpz_gcdext (&gcd, &s, &t, &op1, &op2);
+ if (mpz_cmp (&refgcd, &gcd))
+ dump_abort (&op1, &op2);
+
+ mpz_mul (&temp1, &s, &op1);
+ mpz_mul (&temp2, &t, &op2);
+ mpz_add (&gcd, &temp1, &temp2);
+ if (mpz_cmp (&refgcd, &gcd))
+ dump_abort (&op1, &op2);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refgcd (g, x, y)
+ MP_INT *g;
+ MP_INT *x, *y;
+{
+ MP_INT xx, yy;
+
+ mpz_init (&xx);
+ mpz_init (&yy);
+
+ mpz_abs (&xx, x);
+ mpz_abs (&yy, y);
+
+ for (;;)
+ {
+ if (mpz_cmp_ui (&yy, 0) == 0)
+ {
+ mpz_set (g, &xx);
+ break;
+ }
+ mpz_mod (&xx, &xx, &yy);
+ if (mpz_cmp_ui (&xx, 0) == 0)
+ {
+ mpz_set (g, &yy);
+ break;
+ }
+ mpz_mod (&yy, &yy, &xx);
+ }
+
+ mpz_clear (&xx);
+ mpz_clear (&yy);
+}
+
+dump_abort (op1, op2)
+ MP_INT *op1, *op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-mdm.c b/gnu/lib/libgmp/tests/tst-mdm.c
new file mode 100644
index 0000000..a515ddf
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-mdm.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_divmod, mpz_mdiv,
+ mpz_mdivmod, mpz_mmod, mpz_mul.
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT dividend, divisor;
+ MP_INT quotient, remainder;
+ MP_INT quotient2, remainder2;
+ MP_INT temp;
+ mp_size dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&dividend);
+ mpz_init (&divisor);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+ mpz_init (&quotient2);
+ mpz_init (&remainder2);
+ mpz_init (&temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&divisor, divisor_size);
+ if (mpz_cmp_ui (&divisor, 0) == 0)
+ continue;
+
+ mpz_mdivmod (&quotient, &remainder, &dividend, &divisor);
+ mpz_mdiv (&quotient2, &dividend, &divisor);
+ mpz_mmod (&remainder2, &dividend, &divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (&quotient, &quotient2) != 0)
+ dump_abort (&dividend, &divisor);
+ if (mpz_cmp (&remainder, &remainder2) != 0)
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (&quotient, 0) != 0)
+ if ((mpz_cmp_ui (&quotient, 0) < 0)
+ != ((mpz_cmp_ui (&dividend, 0) ^ mpz_cmp_ui (&divisor, 0)) < 0))
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (&remainder, 0) != 0)
+ if ((mpz_cmp_ui (&remainder, 0) < 0) != (mpz_cmp_ui (&divisor, 0) < 0))
+ dump_abort (&dividend, &divisor);
+
+ mpz_mul (&temp, &quotient, &divisor);
+ mpz_add (&temp, &temp, &remainder);
+ if (mpz_cmp (&temp, &dividend) != 0)
+ dump_abort (&dividend, &divisor);
+
+ mpz_abs (&temp, &divisor);
+ mpz_abs (&remainder, &remainder);
+ if (mpz_cmp (&remainder, &temp) >= 0)
+ dump_abort (&dividend, &divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-mdm_ui.c b/gnu/lib/libgmp/tests/tst-mdm_ui.c
new file mode 100644
index 0000000..26befbe
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-mdm_ui.c
@@ -0,0 +1,116 @@
+/* Test mpz_abs, mpz_add, mpz_cmp. mpz_cmp_si, mpz_cmp_ui, mpz_divmod,
+ mpz_mdiv_ui, mpz_mdivmod_ui, mpz_mmod_ui, mpz_mul, mpz_mul_ui.
+
+Copyright (C) 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT dividend;
+ MP_INT quotient, remainder;
+ MP_INT quotient2, remainder2;
+ MP_INT temp;
+ mp_size dividend_size;
+ mp_limb divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&dividend);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+ mpz_init (&quotient2);
+ mpz_init (&remainder2);
+ mpz_init (&temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_mdivmod_ui (&quotient, &remainder, &dividend, divisor);
+ mpz_mdiv_ui (&quotient2, &dividend, divisor);
+ mpz_mmod_ui (&remainder2, &dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (&quotient, &quotient2) != 0)
+ dump_abort (&dividend, divisor);
+ if (mpz_cmp (&remainder, &remainder2) != 0)
+ dump_abort (&dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (&quotient, 0) != 0)
+ if ((mpz_cmp_ui (&quotient, 0) < 0)
+ != (mpz_cmp_ui (&dividend, 0) < 0))
+ dump_abort (&dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (&remainder, 0) != 0)
+ if (mpz_cmp_ui (&remainder, 0) < 0)
+ dump_abort (&dividend, divisor);
+
+ mpz_mul_ui (&temp, &quotient, divisor);
+ mpz_add (&temp, &temp, &remainder);
+ if (mpz_cmp (&temp, &dividend) != 0)
+ dump_abort (&dividend, divisor);
+
+ mpz_abs (&remainder, &remainder);
+ if (mpz_cmp_ui (&remainder, divisor) >= 0)
+ dump_abort (&dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend;
+ mp_limb divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-mul.c b/gnu/lib/libgmp/tests/tst-mul.c
new file mode 100644
index 0000000..0eab422
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-mul.c
@@ -0,0 +1,261 @@
+/* Test mpz_add, mpz_cmp, mpz_cmp_ui, mpz_divmod, mpz_mul.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "urandom.h"
+
+void debug_mp ();
+mp_size _mpn_mul_classic ();
+void mpz_refmul ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT multiplier, multiplicand;
+ MP_INT product, ref_product;
+ MP_INT quotient, remainder;
+ mp_size multiplier_size, multiplicand_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&multiplier);
+ mpz_init (&multiplicand);
+ mpz_init (&product);
+ mpz_init (&ref_product);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+
+ for (i = 0; i < reps; i++)
+ {
+ multiplier_size = urandom () % SIZE - SIZE/2;
+ multiplicand_size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&multiplier, multiplier_size);
+ mpz_random2 (&multiplicand, multiplicand_size);
+
+ mpz_mul (&product, &multiplier, &multiplicand);
+ mpz_refmul (&ref_product, &multiplier, &multiplicand);
+ if (mpz_cmp_ui (&multiplicand, 0) != 0)
+ mpz_divmod (&quotient, &remainder, &product, &multiplicand);
+
+ if (mpz_cmp (&product, &ref_product))
+ dump_abort (&multiplier, &multiplicand);
+
+ if (mpz_cmp_ui (&multiplicand, 0) != 0)
+ if (mpz_cmp_ui (&remainder, 0) || mpz_cmp (&quotient, &multiplier))
+ dump_abort (&multiplier, &multiplicand);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refmul (w, u, v)
+ MP_INT *w;
+ const MP_INT *u;
+ const MP_INT *v;
+{
+ mp_size usize = u->size;
+ mp_size vsize = v->size;
+ mp_size wsize;
+ mp_size sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me = NULL;
+ size_t free_me_size;
+
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ /* Swap U and V. */
+ {const MP_INT *t = u; u = v; v = t;}
+ {mp_size t = usize; usize = vsize; vsize = t;}
+ }
+
+ up = u->d;
+ vp = v->d;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->alloc < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = w->alloc;
+ }
+ else
+ (*_mp_free_func) (wp, w->alloc * BYTES_PER_MP_LIMB);
+
+ w->alloc = wsize;
+ wp = (mp_ptr) (*_mp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
+ w->d = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = (mp_ptr) alloca (usize * BYTES_PER_MP_LIMB);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = (mp_ptr) alloca (vsize * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ wsize = _mpn_mul_classic (wp, up, usize, vp, vsize);
+ w->size = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ alloca (0);
+}
+
+mp_size
+_mpn_mul_classic (prodp, up, usize, vp, vsize)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size usize;
+ mp_srcptr vp;
+ mp_size vsize;
+{
+ mp_size n;
+ mp_size prod_size;
+ mp_limb cy;
+ mp_size i, j;
+ mp_limb prod_low, prod_high;
+ mp_limb cy_dig;
+ mp_limb v_limb, c;
+
+ if (vsize == 0)
+ return 0;
+
+ /* Offset UP and PRODP so that the inner loop can be faster. */
+ up += usize;
+ prodp += usize;
+
+ /* Multiply by the first limb in V separately, as the result can
+ be stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ cy_dig = 0;
+ j = -usize;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prodp[j], prod_high, prod_low, 0, cy_dig);
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++)
+ {
+ v_limb = vp[i];
+ cy_dig = 0;
+ j = -usize;
+
+ /* Inner loops. Simulate the carry flag by jumping between
+ these loops. The first is used when there was no carry
+ in the previois iteration; the second when there was carry. */
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c;
+ prodp[j] = prod_low;
+ if (prod_low < c)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+ continue;
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c + 1;
+ prodp[j] = prod_low;
+ if (prod_low > c)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ cy_dig += 1;
+ prodp[j] = cy_dig;
+ prodp++;
+ }
+
+ return usize + vsize - (cy_dig == 0);
+}
+
+dump_abort (multiplier, multiplicand)
+ MP_INT *multiplier, *multiplicand;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "multiplier = "); debug_mp (multiplier, -16);
+ fprintf (stderr, "multiplicand = "); debug_mp (multiplicand, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-pow_ui.c b/gnu/lib/libgmp/tests/tst-pow_ui.c
new file mode 100644
index 0000000..c7d929a
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-pow_ui.c
@@ -0,0 +1,120 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_div, mpz_divmod, mpz_mod,
+ mpz_mul.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT dividend, divisor;
+ MP_INT quotient, remainder;
+ MP_INT quotient2, remainder2;
+ MP_INT temp;
+ mp_size dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&dividend);
+ mpz_init (&divisor);
+ mpz_init (&quotient);
+ mpz_init (&remainder);
+ mpz_init (&quotient2);
+ mpz_init (&remainder2);
+ mpz_init (&temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ base_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&base, base_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (&divisor, divisor_size);
+ if (mpz_cmp_ui (&divisor, 0) == 0)
+ continue;
+
+ exp_size = urandom () % SIZE/2;
+ mpz_random2 (&exp, exp_size);
+
+ mpz_powm (&result1, &base, &exp, &divisor);
+ mpz_div (&quotient2, &dividend, &divisor);
+ mpz_mod (&remainder2, &dividend, &divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (&quotient, &quotient2) != 0)
+ dump_abort (&dividend, &divisor);
+ if (mpz_cmp (&remainder, &remainder2) != 0)
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (&quotient, 0) != 0)
+ if ((mpz_cmp_ui (&quotient, 0) < 0)
+ != ((mpz_cmp_ui (&dividend, 0) ^ mpz_cmp_ui (&divisor, 0)) < 0))
+ dump_abort (&dividend, &divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (&remainder, 0) != 0)
+ if ((mpz_cmp_ui (&remainder, 0) < 0) != (mpz_cmp_ui (&dividend, 0) < 0))
+ dump_abort (&dividend, &divisor);
+
+ mpz_mul (&temp, &quotient, &divisor);
+ mpz_add (&temp, &temp, &remainder);
+ if (mpz_cmp (&temp, &dividend) != 0)
+ dump_abort (&dividend, &divisor);
+
+ mpz_abs (&temp, &divisor);
+ mpz_abs (&remainder, &remainder);
+ if (mpz_cmp (&remainder, &temp) >= 0)
+ dump_abort (&dividend, &divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/tst-sqrtrem.c b/gnu/lib/libgmp/tests/tst-sqrtrem.c
new file mode 100644
index 0000000..b62350a
--- /dev/null
+++ b/gnu/lib/libgmp/tests/tst-sqrtrem.c
@@ -0,0 +1,97 @@
+/* Test mpz_add, mpz_add_ui, mpz_cmp, mpz_cmp, mpz_mul, mpz_sqrtrem.
+
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT x2;
+ MP_INT x, rem;
+ MP_INT temp, temp2;
+ mp_size x2_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&x2);
+ mpz_init (&x);
+ mpz_init (&rem);
+ mpz_init (&temp);
+ mpz_init (&temp2);
+
+ for (i = 0; i < reps; i++)
+ {
+ x2_size = urandom () % SIZE;
+
+ mpz_random2 (&x2, x2_size);
+
+ mpz_sqrtrem (&x, &rem, &x2);
+ mpz_mul (&temp, &x, &x);
+
+ /* Is square of result > argument? */
+ if (mpz_cmp (&temp, &x2) > 0)
+ dump_abort (&x2, &x, &rem);
+
+ mpz_add_ui (&temp2, &x, 1);
+ mpz_mul (&temp2, &temp2, &temp2);
+
+ /* Is square of (result + 1) <= argument? */
+ if (mpz_cmp (&temp2, &x2) <= 0)
+ dump_abort (&x2, &x, &rem);
+
+ mpz_add (&temp2, &temp, &rem);
+
+ /* Is the remainder wrong? */
+ if (mpz_cmp (&x2, &temp2) != 0)
+ dump_abort (&x2, &x, &rem);
+ }
+
+ exit (0);
+}
+
+dump_abort (x2, x, rem)
+ MP_INT *x2, *x, *rem;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "x2 = "); debug_mp (x2, -16);
+ fprintf (stderr, "x = "); debug_mp (x, -16);
+ fprintf (stderr, "remainder = "); debug_mp (rem, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/tests/urandom.h b/gnu/lib/libgmp/tests/urandom.h
new file mode 100644
index 0000000..e018580
--- /dev/null
+++ b/gnu/lib/libgmp/tests/urandom.h
@@ -0,0 +1,17 @@
+#if defined (hpux) || defined (__alpha__)
+/* HPUX lacks random(). DEC Alpha's random() returns a double. */
+static inline unsigned long
+urandom ()
+{
+ return mrand48 ();
+}
+#else
+long random ();
+
+static inline unsigned long
+urandom ()
+{
+ /* random() returns 31 bits, we want 32. */
+ return random() ^ (random() << 1);
+}
+#endif
diff --git a/gnu/lib/libgmp/texinfo.tex b/gnu/lib/libgmp/texinfo.tex
new file mode 100644
index 0000000..1536ac3
--- /dev/null
+++ b/gnu/lib/libgmp/texinfo.tex
@@ -0,0 +1,4585 @@
+%% TeX macros to handle texinfo files
+
+% Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
+% 94, 95, 1996 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!
+
+
+% Send bug reports to bug-texinfo@prep.ai.mit.edu.
+% Please include a *precise* test case in each bug report.
+
+
+% Make it possible to create a .fmt file just by loading this file:
+% if the underlying format is not loaded, start by loading it now.
+% Added by gildea November 1993.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+
+% This automatically updates the version number based on RCS.
+\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
+\deftexinfoversion$Revision: 2.172 $
+\message{Loading texinfo package [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]}\message{}
+ \catcode`+=\active \catcode`\_=\active}
+
+% Save some parts of plain tex whose names we will redefine.
+
+\let\ptextilde=\~
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexdots=\dots
+\let\ptexdot=\.
+\let\ptexstar=\*
+\let\ptexend=\end
+\let\ptexbullet=\bullet
+\let\ptexb=\b
+\let\ptexc=\c
+\let\ptexi=\i
+\let\ptext=\t
+\let\ptexl=\l
+\let\ptexL=\L
+
+% 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\ }
+}
+\let\~ = \tie % And make it available as @~.
+
+\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.
+\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi%
+\def\putwordInfo{Info}%
+\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi%
+\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi%
+\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi%
+\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi%
+\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi%
+\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi%
+\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi%
+\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi%
+\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi%
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+\hyphenation{ap-pen-dix}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{eshell}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen \bindingoffset \bindingoffset=0pt
+\newdimen \normaloffset \normaloffset=\hoffset
+\newdimen\pagewidth \newdimen\pageheight
+\pagewidth=\hsize \pageheight=\vsize
+
+% 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}%
+\def\loggingall{\tracingcommands2 \tracingstats2
+ \tracingpages1 \tracingoutput1 \tracinglostchars1
+ \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+ \showboxbreadth\maxdimen\showboxdepth\maxdimen
+}%
+
+%---------------------Begin change-----------------------
+%
+%%%% For @cropmarks command.
+% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\cornerlong \newdimen\cornerthick
+\newdimen \topandbottommargin
+\newdimen \outerhsize \newdimen \outervsize
+\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
+\outerhsize=7in
+%\outervsize=9.5in
+% Alternative @smallbook page size is 9.25in
+\outervsize=9.25in
+\topandbottommargin=.75in
+%
+%---------------------End change-----------------------
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions itself, but you have to call it yourself.
+\chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}}
+\def\onepageout#1{\hoffset=\normaloffset
+\ifodd\pageno \advance\hoffset by \bindingoffset
+\else \advance\hoffset by -\bindingoffset\fi
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}%
+{\let\hsize=\pagewidth \makefootline}}}%
+\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+
+%%%% For @cropmarks command %%%%
+
+% Here is a modification of the main output routine for Near East Publications
+% This provides right-angle cropmarks at all four corners.
+% The contents of the page are centerlined into the cropmarks,
+% and any desired binding offset is added as an \hskip on either
+% site of the centerlined box. (P. A. MacKay, 12 November, 1986)
+%
+\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+ \shipout
+ \vbox to \outervsize{\hsize=\outerhsize
+ \vbox{\line{\ewtop\hfill\ewtop}}
+ \nointerlineskip
+ \line{\vbox{\moveleft\cornerthick\nstop}
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}}
+ \vskip \topandbottommargin
+ \centerline{\ifodd\pageno\hskip\bindingoffset\fi
+ \vbox{
+ {\let\hsize=\pagewidth \makeheadline}
+ \pagebody{#1}
+ {\let\hsize=\pagewidth \makefootline}}
+ \ifodd\pageno\else\hskip\bindingoffset\fi}
+ \vskip \topandbottommargin plus1fill minus1fill
+ \boxmaxdepth\cornerthick
+ \line{\vbox{\moveleft\cornerthick\nsbot}
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}}
+ \nointerlineskip
+ \vbox{\line{\ewbot\hfill\ewbot}}
+ }}
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+%
+% Do @cropmarks to get crop marks
+\def\cropmarks{\let\onepageout=\croppageout }
+
+\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. Type 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{Type <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 \char '100}}
+
+% 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 \char '173}}
+\def\myrbrace {{\tt \char '175}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+
+% @: 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 }
+
+% @enddots{} is an end-of-sentence ellipsis.
+\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000}
+
+% @! is an end-of-sentence bang.
+\gdef\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\gdef\?{?\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\penalty 10000
+%\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 some dots
+
+\def\dots{$\ldots$}
+
+% @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{\par \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{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
+\parsearg \commentxxx}
+
+\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
+
+\let\c=\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\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
+ \let\message = \relax
+}
+
+% Ignore @ignore ... @end ignore.
+%
+\def\ignore{\doignore{ignore}}
+
+% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text.
+%
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifhtml{\doignore{ifhtml}}
+\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.
+
+\def\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'.
+ \long\def\doignoretext##1\end #1{\enddoignore}%
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \catcode32 = 10
+ %
+ % 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{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}}
+}
+
+% @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 \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.
+%
+\def\value#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 always succeeds; we read the text following, through @end
+% iftex). But `@end iftex' should be valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\defineunmatchedend{iftex}
+
+% 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}
+
+\def\node{\ENVcheck\parsearg\nodezzz}
+\def\nodezzz#1{\nodexxx [#1,]}
+\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\relax
+
+\def\donoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\setref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\unnumbnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\appendixnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\let\refill=\relax
+
+% @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{%
+ \readauxfile
+ \opencontents
+ \openindices
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+ \comment % Ignore the actual filename.
+}
+
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+\def\macro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\macroxxx}
+\def\macroxxx#1#2 \end macro{%
+\expandafter\gdef\macrotemp#1{#2}%
+\endgroup}
+
+%\def\linemacro#1{\begingroup\ignoresections\catcode`\#=6\def\macrotemp{#1}\parsearg\linemacroxxx}
+%\def\linemacroxxx#1#2 \end linemacro{%
+%\let\parsearg=\relax
+%\edef\macrotempx{\csname M\butfirst\expandafter\string\macrotemp\endcsname}%
+%\expandafter\xdef\macrotemp{\parsearg\macrotempx}%
+%\expandafter\gdef\macrotempx#1{#2}%
+%\endgroup}
+
+%\def\butfirst#1{}
+
+\message{fonts,}
+
+% Font-change commands.
+
+% Texinfo 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}
+
+%% Try out Computer Modern fonts at \magstephalf
+\let\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.
+% 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\indrm\rmshape{9}{1000}
+\setfont\indit\slshape{9}{1000}
+\let\indsl=\indit
+\let\indtt=\ninett
+\let\indttsl=\ninett
+\let\indsf=\indrm
+\let\indbf=\indrm
+\setfont\indsc\scshape{10}{900}
+\font\indi=cmmi9
+\font\indsy=cmsy9
+
+% Fonts for headings
+\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{12}{\magstep2}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+\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
+
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{\magstep1}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{\magstep1}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled \magstep1
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% Fonts for title page:
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\let\authorrm = \secrm
+
+% 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\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}
+\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}
+\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}
+\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}
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% 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\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartitalic
+\let\dfn=\smartitalic
+\let\emph=\smartitalic
+\let\cite=\smartitalic
+
+\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}
+\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+\let\file=\samp
+\let\url=\samp % perhaps include a hypertex \special eventually
+
+% @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 an a dash.
+% -- rms.
+{
+\catcode`\-=\active
+\catcode`\_=\active
+\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
+% The following is used by \doprintindex to insure that long function names
+% wrap around. It is necessary for - and _ to be active before the index is
+% read from the file, as \entry parses the arguments long before \code is
+% ever called. -- mycroft
+\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
+}
+
+\def\realdash{-}
+\def\realunder{_}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{\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.
+%
+\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{\ttsl\look}}\fi
+\else{\tclose{\ttsl\look}}\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}
+
+\def\l#1{{\li #1}\null} %
+
+\def\r#1{{\rm #1}} % roman font
+% Use of \lowercase was suggested.
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\def\titlefont#1{{\titlerm #1}}
+
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+\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
+% I deinstalled the following change because \cmr12 is undefined.
+% This change was not in the ChangeLog anyway. --rms.
+% \let\subtitlerm=\cmr12
+ \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{\titlefont{##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
+ \HEADINGSon
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks \evenheadline % Token sequence for heading line of even pages
+\newtoks \oddheadline % Token sequence for heading line of odd pages
+\newtoks \evenfootline % Token sequence for footing line of even pages
+\newtoks \oddfootline % Token sequence for footing line of 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{\everyheadingyyy #1@|@|@|@|\finish}
+\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\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}}}
+
+\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish}
+\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+%
+}% 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.
+
+\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{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+\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}}
+}
+
+\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}}
+}
+
+% 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,}
+
+% @tabs -- simple alignment
+
+% These don't work. For one thing, \+ is defined as outer.
+% So these macros cannot even be defined.
+
+%\def\tabs{\parsearg\tabszzz}
+%\def\tabszzz #1{\settabs\+#1\cr}
+%\def\tabline{\parsearg\tablinezzz}
+%\def\tablinezzz #1{\+#1\cr}
+%\def\&{&}
+
+% 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.
+ %
+ % Be sure we are not still in the middle of a paragraph.
+ %{\parskip = 0in
+ %\par
+ %}%
+ %
+ % 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. Since that
+ % text will be indented by \tableindent, we make the item text be in
+ % a zero-width box.
+ \noindent
+ \rlap{\hskip -\tableindent\box0}\ignorespaces%
+ \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}{}{}{}{}}
+
+\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 itemsize
+ \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 <number>.
+ %
+ \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, @multicolumn or @endmulticolumn 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.
+
+%%%%
+% Dimensions
+
+\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
+
+%% 2/1/96, to allow fractions to be given with more than one digit.
+\def\pickupwholefraction#1 {\global\advance\colcount by1 %
+\expandafter\xdef\csname col\the\colcount\endcsname{.#1\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 % In this case arg of setuptable
+ % is the decimal point before the
+ % number given in percent of hsize.
+ % We don't need this so we don't use it.
+ \else
+ \global\advance\colcount by1
+ \setbox0=\hbox{#1}%
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi%
+ \fi%
+\ifx\go\pickupwholefraction\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
+\let\item\cr
+\tolerance=9500
+\hbadness=9500
+\setmultitablespacing
+\parskip=\multitableparskip
+\parindent=\multitableparindent
+\overfullrule=0pt
+\global\colcount=0\relax%
+\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
+ % To parse everything between @multitable and @item :
+\setuptable#1 \endsetuptable
+ % Need to reset this to 0 after \setuptable.
+\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 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.
+\ifnum\colcount=1
+\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
+\noindent##}\cr%
+ % \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.
+\global\everycr{\noalign{%
+\filbreak%% keeps underfull box messages off when table breaks over pages.
+\global\colcount=0\relax}}
+}
+
+\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.
+\setbox0=\vbox{Xy}
+\ifdim\multitablelinespace=0pt
+%% strut to put in table in case some entry doesn't have descenders,
+%% to keep lines equally spaced
+\gdef\multistrut{\vrule height\ht0 depth\dp0 width0pt\relax}
+%% 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{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\doindex {#1}}
+}
+
+% @defindex foo == \newindex{foo}
+
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+
+\def\newcodeindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\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.
+\def\synindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\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\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{%
+% 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.
+\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\char{\realbackslash char}%
+\def\TeX{\realbackslash TeX}%
+\def\dots{\realbackslash dots }%
+\def\copyright{\realbackslash copyright }%
+\def\tclose##1{\realbackslash tclose {##1}}%
+\def\code##1{\realbackslash code {##1}}%
+\def\samp##1{\realbackslash samp {##1}}%
+\def\t##1{\realbackslash r {##1}}%
+\def\r##1{\realbackslash r {##1}}%
+\def\i##1{\realbackslash i {##1}}%
+\def\b##1{\realbackslash b {##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}}%
+\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\b=\indexdummyfont
+\let\c=\indexdummyfont
+\let\d=\indexdummyfont
+\let\u=\indexdummyfont
+\let\v=\indexdummyfont
+\let\H=\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\file=\indexdummyfont
+\let\samp=\indexdummyfont
+\let\kbd=\indexdummyfont
+\let\key=\indexdummyfont
+\let\var=\indexdummyfont
+\let\TeX=\indexdummytex
+\let\dots=\indexdummydots
+}
+
+% 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 %initialize!
+% workhorse for all \fooindexes
+% #1 is name of index, #2 is stuff to put there
+\def\doind #1#2{%
+% Put the index entry in the margin if desired.
+\ifx\SETmarginindex\relax\else%
+\insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+\fi%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0% 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 in the indx.
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}}}%
+\temp }%
+}\penalty\count10}}
+
+\def\dosubind #1#2#3{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0%
+\def\rawbackslashxx{\indexbackslash}%
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2 #3}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}{#3}}}%
+\temp }%
+}\penalty\count10}}
+
+% 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.
+
+% This is what you call to cause a particular index to get printed.
+% Write
+% @unnumbered Function Index
+% @printindex fn
+
+\def\printindex{\parsearg\doprintindex}
+
+\def\doprintindex#1{%
+ \tex
+ \dobreak \chapheadingskip {10000}
+ \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other
+ \catcode`\$=\other
+ \catcode`\~=\other
+ \indexbreaks
+ %
+ % The following don't help, since the chars were translated
+ % when the raw index was written, and their fonts were discarded
+ % due to \indexnofonts.
+ %\catcode`\"=\active
+ %\catcode`\^=\active
+ %\catcode`\_=\active
+ %\catcode`\|=\active
+ %\catcode`\<=\active
+ %\catcode`\>=\active
+ % %
+ \def\indexbackslash{\rawbackslashxx}
+ \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
+ \begindoublecolumns
+ %
+ % See if the index file exists and is nonempty.
+ \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
+ \input \jobname.#1s
+ \fi
+ \fi
+ \closein 1
+ \enddoublecolumns
+ \Etex
+}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+% Same as \bigskipamount except no shrink.
+% \balancecolumns gets confused if there is any shrink.
+\newskip\initialskipamount \initialskipamount 12pt plus4pt
+
+\def\initial #1{%
+{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+\ifdim\lastskip<\initialskipamount
+\removelastskip \penalty-200 \vskip \initialskipamount\fi
+\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+
+% 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
+ %
+ % 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 is used in indexes.
+%% Adapted from the TeXbook, page 416.
+\catcode `\@=11
+
+\newbox\partialpage
+
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup
+ % Grab any single-column material above us.
+ \output = {\global\setbox\partialpage
+ =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
+ \eject
+ %
+ % Now switch to the double-column output routine.
+ \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 once.
+ %
+ % 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.)
+ \vsize = 2\vsize
+ \doublecolumnpagegoal
+}
+
+\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage}
+
+\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth
+ \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage
+ \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1}
+ \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3}
+ \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+ \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+}
+\def\doublecolumnpagegoal{%
+ \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@
+}
+\def\pagesofar{\unvbox\partialpage %
+ \hsize=\doublecolumnhsize % have to restore this since output routine
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
+\def\doublecolumnout{%
+ \setbox5=\copy255
+ {\vbadness=10000 \doublecolumnsplit}
+ \ifvbox255
+ \setbox0=\vtop to\dimen@{\unvbox0}
+ \setbox2=\vtop to\dimen@{\unvbox2}
+ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty
+ \else
+ \setbox0=\vbox{\unvbox5}
+ \ifvbox0
+ \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ {\vbadness=10000
+ \loop \global\setbox5=\copy0
+ \setbox1=\vsplit5 to\dimen@
+ \setbox3=\vsplit5 to\dimen@
+ \ifvbox5 \global\advance\dimen@ by1pt \repeat
+ \setbox0=\vbox to\dimen@{\unvbox1}
+ \setbox2=\vbox to\dimen@{\unvbox3}
+ \global\setbox\partialpage=\vbox{\pagesofar}
+ \doublecolumnpagegoal
+ }
+ \fi
+ \fi
+}
+
+\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}
+
+\newwrite \contentsfile
+% This is called from \setfilename.
+\def\opencontents{\openout \contentsfile = \jobname.toc}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise
+
+\def\thischapter{} \def\thissection{}
+\def\seccheck#1{\if \pageno<0 %
+\errmessage{@#1 not allowed after generating table of contents}\fi
+%
+}
+
+\def\chapternofonts{%
+\let\rawbackslash=\relax%
+\let\frenchspacing=\relax%
+\def\result{\realbackslash result}
+\def\equiv{\realbackslash equiv}
+\def\expansion{\realbackslash expansion}
+\def\print{\realbackslash print}
+\def\TeX{\realbackslash TeX}
+\def\dots{\realbackslash dots}
+\def\copyright{\realbackslash copyright}
+\def\tt{\realbackslash tt}
+\def\bf{\realbackslash bf }
+\def\w{\realbackslash w}
+\def\less{\realbackslash less}
+\def\gtr{\realbackslash gtr}
+\def\hat{\realbackslash hat}
+\def\char{\realbackslash char}
+\def\tclose##1{\realbackslash tclose {##1}}
+\def\code##1{\realbackslash code {##1}}
+\def\samp##1{\realbackslash samp {##1}}
+\def\r##1{\realbackslash r {##1}}
+\def\b##1{\realbackslash b {##1}}
+\def\key##1{\realbackslash key {##1}}
+\def\file##1{\realbackslash file {##1}}
+\def\kbd##1{\realbackslash kbd {##1}}
+% These are redefined because @smartitalic wouldn't work inside xdef.
+\def\i##1{\realbackslash i {##1}}
+\def\cite##1{\realbackslash cite {##1}}
+\def\var##1{\realbackslash var {##1}}
+\def\emph##1{\realbackslash emph {##1}}
+\def\dfn##1{\realbackslash dfn {##1}}
+}
+
+\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
+}
+
+
+\def\thischaptername{No Chapter Title}
+\outer\def\chapter{\parsearg\chapteryyy}
+\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz #1{\seccheck{chapter}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \chapno by 1 \message{\putwordChapter \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}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \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{\seccheck{appendix}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
+\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry
+ {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \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}}}
+
+\outer\def\top{\parsearg\unnumberedyyy}
+\outer\def\unnumbered{\parsearg\unnumberedyyy}
+\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz #1{\seccheck{unnumbered}%
+\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<toks register> to achieve this: TeX expands \the<toks> only once,
+% simply yielding the contents of the <toks register>.
+\toks0 = {#1}\message{(\the\toks0)}%
+%
+\unnumbchapmacro {#1}%
+\gdef\thischapter{#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\global\let\section = \unnumberedsec
+\global\let\subsection = \unnumberedsubsec
+\global\let\subsubsection = \unnumberedsubsubsec
+}}
+
+\outer\def\numberedsec{\parsearg\secyyy}
+\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+\def\seczzz #1{\seccheck{section}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsection{\parsearg\appendixsecyyy}
+\outer\def\appendixsec{\parsearg\appendixsecyyy}
+\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz #1{\seccheck{appendixsection}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz #1{\seccheck{subsection}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry %
+ {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
+ {\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry{#1}%
+ {\appendixletter}
+ {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+% 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}
+
+\def\heading{\parsearg\secheadingi}
+
+\def\subheading{\parsearg\subsecheadingi}
+
+\def\subsubheading{\parsearg\subsubsecheadingi}
+
+% 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 \chapheadingskip = 30pt plus 8pt minus 4pt
+
+\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\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{
+\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}
+
+\def\chfplain #1#2{%
+ \pchapsepmacro
+ {%
+ \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #2\enspace #1}%
+ }%
+ \bigskip
+ \penalty5000
+}
+
+\def\unnchfplain #1{%
+\pchapsepmacro %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\centerchfplain #1{%
+\pchapsepmacro %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ {\rm #1}\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\CHAPFplain % The default
+
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\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\penalty 10000 %
+}
+
+\def\CHAPFopen{
+\global\let\chapmacro=\chfopen
+\global\let\unnumbchapmacro=\unnchfopen
+\global\let\centerchapmacro=\centerchfopen}
+
+% Parameter controlling skip before section headings.
+
+\newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt
+\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+
+\newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+
+% @paragraphindent is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
+% Section fonts are the base font at magstep2, which produces
+% a size a bit more than 14 points in the default situation.
+
+\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}}
+\def\plainsecheading #1{\secheadingi {#1}}
+\def\secheadingi #1{{\advance \secheadingskip by \parskip %
+\secheadingbreak}%
+{\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+
+% Subsection fonts are the base font at magstep1,
+% which produces a size of 12 points.
+
+\def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}}
+\def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+\def\subsubsecfonts{\subsecfonts} % Maybe this should change:
+ % Perhaps make sssec fonts scaled
+ % magstep half
+\def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}}
+\def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000}
+
+
+\message{toc printing,}
+
+% Finish up the main text and prepare to read what we've written
+% to \contentsfile.
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\def\startcontents#1{%
+ \pagealignmacro
+ \immediate\closeout \contentsfile
+ \ifnum \pageno>0
+ \pageno = -1 % Request roman numbered pages.
+ \fi
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \unnumbchapmacro{#1}\def\thischapter{}%
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ \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.
+}
+
+
+% Normal (long) toc.
+\outer\def\contents{%
+ \startcontents{\putwordTableofContents}%
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+
+% And just the chapters.
+\outer\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
+ \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{}
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+\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 in \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 would want to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno{#2}}%
+ \endgroup
+ \nobreak\vskip .25\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.)
+%
+% \turnoffactive is for the sake of @" used for umlauts.
+\def\tocentry#1#2{\begingroup
+ \hyphenpenalty = 10000
+ \entry{\turnoffactive #1}{\turnoffactive #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
+
+\let\ptexequiv = \equiv
+
+%{\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}
+%}
+
+\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
+\catcode`\"=12
+\catcode`\==12
+\catcode`\|=12
+\catcode`\<=12
+\catcode`\>=12
+\escapechar=`\\
+%
+\let\~=\ptextilde
+\let\{=\ptexlbrace
+\let\}=\ptexrbrace
+\let\.=\ptexdot
+\let\*=\ptexstar
+\let\dots=\ptexdots
+\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}
+\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}
+\def\@{@}%
+\let\bullet=\ptexbullet
+\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl
+\let\L=\ptexL
+%
+\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: draw rectangle w/rounded corners around argument
+\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 18pt % allow for 3pt kerns on either
+% side, and for 6pt waste from
+% each corner char
+ \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
+}
+
+% To ending 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}%
+
+% This macro is
+\def\lisp{\begingroup
+ \nonfillstart
+ \let\Elisp = \nonfillfinish
+ \tt
+ \rawbackslash % have \ input char produce \ char from current font
+ \gobble
+}
+
+% Define the \E... control sequence only if we are inside the
+% environment, so the error checking in \end will work.
+%
+% We must call \lisp last in the definition, since it reads the
+% return following the @example (or whatever) command.
+%
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp. This is not used unless the @smallbook
+% command is given. Originally contributed by Pavel@xerox.
+%
+\def\smalllispx{\begingroup
+ \nonfillstart
+ \let\Esmalllisp = \nonfillfinish
+ \let\Esmallexample = \nonfillfinish
+ %
+ % Smaller interline space and fonts for small examples.
+ \setleading{10pt}%
+ \indexfonts \tt
+ \rawbackslash % make \ output the \ character from the current font (tt)
+ \gobble
+}
+
+% This is @display; same as @lisp except use roman font.
+%
+\def\display{\begingroup
+ \nonfillstart
+ \let\Edisplay = \nonfillfinish
+ \gobble
+}
+
+% This is @format; same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eformat = \nonfillfinish
+ \gobble
+}
+
+% @flushleft (same as @format) and @flushright.
+%
+\def\flushleft{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushleft = \nonfillfinish
+ \gobble
+}
+\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\&#1}\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`\(}} \def\clnr{{\sf\char`\)}} \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
+\dimen3=\rightskip
+\advance\dimen3 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 \advance \hsize by -\dimen3
+\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
+% 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 \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active % 61 is `='
+\obeylines\activeparens\spacesplit#3}
+
+\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 \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+
+\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 \advance \rightskip 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 \advance \rightskip 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 \advance \rightskip 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, putting the result in \tptemp.
+%
+\def\removeemptybraces\empty#1\relax{\def\tptemp{#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{%
+ \removeemptybraces#2\relax
+ #1{\tptemp}{#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 \advance \rightskip 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 parens in @def arguments}\fi%
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+\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\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+% 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\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}}
+
+% @defmethod, and so on
+
+% @defop {Funny Method} foo-class frobnicate argument
+
+\def\defop #1 {\def\defoptype{#1}%
+\defopparsebody\Edefop\defopx\defopheader\defoptype}
+
+\def\defopheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
+\begingroup\defname {#2}{\defoptype{} on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defmethod == @defop Method
+
+\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+
+\def\defmethodheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% entry in function index
+\begingroup\defname {#2}{Method on #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\penalty 10000\vskip -\parskip\penalty 10000}
+
+% @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.
+\def\deftypevarheader #1#2{%
+\doind {vr}{\code{#2}}% Make entry in variables index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% @deftypevr {Global Flag} int enable
+
+\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+
+\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
+\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\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{cross reference,}
+% Define cross-reference macros
+\newwrite \auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% \setref{foo} defines a cross-reference point named foo.
+
+\def\setref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ysectionnumberandtype}}
+
+\def\unnumbsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ynothing}}
+
+\def\appendixsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Yappendixletterandtype}}
+
+% \xref, \pxref, and \ref generate cross-references to specified points.
+% 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.
+ {\turnoffactive \refx{#1-snt}{}}%
+ \space [\printednodename],\space
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+\endgroup}
+
+% \dosetq is the interface for calls from other macros
+
+% Use \turnoffactive so that punctuation chars such as underscore
+% work in node names.
+\def\dosetq #1#2{{\let\folio=0 \turnoffactive \auxhat%
+\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
+\next}}
+
+% \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.
+ $\langle$un\-de\-fined$\rangle$%
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \csname X#1\endcsname
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+
+% This is the macro invoked by entries in the aux file.
+\def\xrdef #1#2{
+{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
+
+\def\readauxfile{%
+\begingroup
+\catcode `\^^@=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\^^C=\other
+\catcode `\^^D=\other
+\catcode `\^^E=\other
+\catcode `\^^F=\other
+\catcode `\^^G=\other
+\catcode `\^^H=\other
+\catcode `\ =\other
+\catcode `\^^L=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode 26=\other
+\catcode `\^^[=\other
+\catcode `\^^\=\other
+\catcode `\^^]=\other
+\catcode `\^^^=\other
+\catcode `\^^_=\other
+\catcode `\@=\other
+\catcode `\^=\other
+\catcode `\~=\other
+\catcode `\[=\other
+\catcode `\]=\other
+\catcode`\"=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode `\$=\other
+\catcode `\#=\other
+\catcode `\&=\other
+% `\+ does not work, so use 43.
+\catcode 43=\other
+% 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.
+% 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`\^=7 % to make ^^e4 etc usable in xref tags
+\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.
+\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.
+%
+\long\gdef\footnotezzz#1{\insert\footins{%
+ % 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
+ #1\strut}%
+}
+
+}%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}
+
+
+% End of control word definitions.
+
+\message{and turning on texinfo input format.}
+
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% Set some numeric style parameters, for 8.5 x 11 format.
+
+%\hsize = 6.5in
+\newdimen\defaultparindent \defaultparindent = 15pt
+\parindent = \defaultparindent
+\parskip 18pt plus 1pt
+\setleading{15pt}
+\advance\topskip by 1.2cm
+
+% Prevent underfull vbox error messages.
+\vbadness=10000
+
+% 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.
+%
+\ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+\else
+ \emergencystretch = \hsize
+ \divide\emergencystretch by 45
+\fi
+
+% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25)
+\def\smallbook{
+
+% These values for secheadingskip and subsecheadingskip are
+% experiments. RJC 7 Aug 1992
+\global\secheadingskip = 17pt plus 6pt minus 3pt
+\global\subsecheadingskip = 14pt plus 6pt minus 3pt
+
+\global\lispnarrowing = 0.3in
+\setleading{12pt}
+\advance\topskip by -1cm
+\global\parskip 3pt plus 1pt
+\global\hsize = 5in
+\global\vsize=7.5in
+\global\tolerance=700
+\global\hfuzz=1pt
+\global\contentsrightmargin=0pt
+\global\deftypemargin=0pt
+\global\defbodyindent=.5cm
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+
+\global\let\smalllisp=\smalllispx
+\global\let\smallexample=\smalllispx
+\global\def\Esmallexample{\Esmalllisp}
+}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{
+\global\tolerance=700
+\global\hfuzz=1pt
+\setleading{12pt}
+\global\parskip 15pt plus 1pt
+
+\global\vsize= 53\baselineskip
+\advance\vsize by \topskip
+%\global\hsize= 5.85in % A4 wide 10pt
+\global\hsize= 6.5in
+\global\outerhsize=\hsize
+\global\advance\outerhsize by 0.5in
+\global\outervsize=\vsize
+\global\advance\outervsize by 0.6in
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+}
+
+% Allow control of the text dimensions. Parameters in order: textheight;
+% textwidth; voffset; hoffset; binding offset; topskip.
+% All require a dimension;
+% header is additional; added length extends the bottom of the page.
+
+\def\changepagesizes#1#2#3#4#5#6{
+ \global\vsize= #1
+ \global\topskip= #6
+ \advance\vsize by \topskip
+ \global\voffset= #3
+ \global\hsize= #2
+ \global\outerhsize=\hsize
+ \global\advance\outerhsize by 0.5in
+ \global\outervsize=\vsize
+ \global\advance\outervsize by 0.6in
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ \global\normaloffset= #4
+ \global\bindingoffset= #5}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper. Top margin
+% 29mm, hence bottom margin 28mm, nominal side margin 3cm.
+\def\afourlatex
+ {\global\tolerance=700
+ \global\hfuzz=1pt
+ \setleading{12pt}
+ \global\parskip 15pt plus 1pt
+ \advance\baselineskip by 1.6pt
+ \changepagesizes{237mm}{150mm}{3.6mm}{3.6mm}{3mm}{7mm}
+ }
+
+% Use @afourwide to print on European A4 paper in wide format.
+\def\afourwide{\afourpaper
+\changepagesizes{9.5in}{6.5in}{\hoffset}{\normaloffset}{\bindingoffset}{7mm}}
+
+% 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 \char '042}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt \char '176}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def\auxhat{\def^{'hat}}
+\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 \char '174}}
+\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 page-delimiter: "^\\\\message"
+@c End:
diff --git a/gnu/lib/libgmp/urandom.h b/gnu/lib/libgmp/urandom.h
new file mode 100644
index 0000000..994e7bd
--- /dev/null
+++ b/gnu/lib/libgmp/urandom.h
@@ -0,0 +1,64 @@
+/* urandom.h -- define urandom returning a full unsigned long random value.
+
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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 MP 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. */
+
+#if defined (__hpux) || defined (__svr4__) || defined (__SVR4)
+/* HPUX lacks random(). */
+static inline unsigned long
+urandom ()
+{
+ return mrand48 ();
+}
+#define __URANDOM
+#endif
+
+#if defined (__alpha) && !defined (__URANDOM)
+/* DEC OSF/1 1.2 random() returns a double. */
+long mrand48 ();
+static inline unsigned long
+urandom ()
+{
+ return mrand48 () | (mrand48 () << 32);
+}
+#define __URANDOM
+#endif
+
+#if BITS_PER_MP_LIMB == 32 && !defined (__URANDOM)
+long random ();
+static inline unsigned long
+urandom ()
+{
+ /* random() returns 31 bits, we want 32. */
+ return random () ^ (random () << 1);
+}
+#define __URANDOM
+#endif
+
+#if BITS_PER_MP_LIMB == 64 && !defined (__URANDOM)
+long random ();
+static inline unsigned long
+urandom ()
+{
+ /* random() returns 31 bits, we want 64. */
+ return random () ^ (random () << 31) ^ (random () << 62);
+}
+#define __URANDOM
+#endif
+
diff --git a/gnu/lib/libgmp/version.c b/gnu/lib/libgmp/version.c
new file mode 100644
index 0000000..7050239
--- /dev/null
+++ b/gnu/lib/libgmp/version.c
@@ -0,0 +1 @@
+static char *gmp_version = "2.0.1";
diff --git a/gnu/lib/libgmp/xtom.c b/gnu/lib/libgmp/xtom.c
new file mode 100644
index 0000000..13f31c8
--- /dev/null
+++ b/gnu/lib/libgmp/xtom.c
@@ -0,0 +1,41 @@
+/* xtom -- convert a hexadecimal string to a MINT, and return a pointer to
+ the MINT.
+
+Copyright (C) 1991 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP 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 MP 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.
+
+You should have received a copy of the GNU General Public License
+along with the GNU MP Library; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "mp.h"
+#include "gmp.h"
+#include "gmp-impl.h"
+
+MINT *
+#ifdef __STDC__
+xtom (const char *hex_str)
+#else
+xtom (hex_str)
+ const char *hex_str;
+#endif
+{
+ MINT *x = (MINT *) (*_mp_allocate_func) (sizeof (MINT));
+
+ x->alloc = 1;
+ x->d = (mp_ptr) (*_mp_allocate_func) (x->alloc * BYTES_PER_MP_LIMB);
+
+ _mpz_set_str (x, hex_str, 16);
+ return x;
+}
diff --git a/gnu/lib/libmp/Makefile b/gnu/lib/libmp/Makefile
new file mode 100644
index 0000000..6298f57
--- /dev/null
+++ b/gnu/lib/libmp/Makefile
@@ -0,0 +1,42 @@
+# Makefile for libmp
+# $Id: Makefile,v 1.4 1995/11/25 00:13:57 peter Exp $
+
+LIB= mp
+SRCS= $(MP_SRCS)
+.PATH: ${.CURDIR}/../libgmp
+CLEANFILES+= cre-mparam cre-conv-tab gmp-mparam.h mp_bases.c
+
+MP_SRCS= mp_bases.c $(BSDMP_SRCS) $(MPN_SRCS) $(IMPL_SRCS)
+
+CFLAGS+= -I${.CURDIR}/../libgmp -I${.OBJDIR} -Wall -Wstrict-prototypes \
+ -DLOCALE -DBERKELEY_MP
+
+BSDMP_SRCS= mpz_gcd.c mpz_add.c mpz_cmp.c mpz_sub.c mpz_mul.c \
+ mpz_powm.c mpz_pow_ui.c mpz_sqrtrem.c mpz_sizeinb.c \
+ itom.c mdiv.c move.c mtox.c xtom.c sdiv.c mout.c min.c mfree.c
+
+MPN_SRCS= mpn_add.c mpn_sub.c mpn_cmp.c mpn_mul.c mpn_div.c mpn_dm_1.c \
+ mpn_mod_1.c mpn_lshift.c mpn_rshift.c mpn_rshiftci.c mpn_sqrt.c
+
+IMPL_SRCS= memory.c mp_set_fns.c _mpz_set_str.c _mpz_get_str.c \
+ mpz_realloc.c mp_clz_tab.c
+
+beforedepend: gmp-mparam.h mp_bases.c
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/../libgmp/mp.h ${DESTDIR}/usr/include/mp.h
+
+cre-mparam: cre-mparam.c
+ $(CC) $(CFLAGS) ${.CURDIR}/../libgmp/cre-mparam.c -o ${.TARGET}
+
+cre-conv-tab: cre-conv-tab.c gmp-mparam.h
+ $(CC) $(CFLAGS) -lm ${.CURDIR}/../libgmp/cre-conv-tab.c -o ${.TARGET}
+
+gmp-mparam.h: cre-mparam
+ ./cre-mparam > ${.TARGET}
+
+mp_bases.c: cre-conv-tab
+ ./cre-conv-tab > ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libobjc/Makefile b/gnu/lib/libobjc/Makefile
new file mode 100644
index 0000000..2083d23
--- /dev/null
+++ b/gnu/lib/libobjc/Makefile
@@ -0,0 +1,33 @@
+# Makefile for libobjc
+# $Id$
+
+GCCDIR= ${.CURDIR}/../../../contrib/gcc
+
+.PATH: ${GCCDIR}/objc
+
+LIB= objc
+NOMAN= sorry
+NOPIC= does not work
+
+SRCS= archive.c class.c encoding.c hash.c init.c misc.c \
+ my_objects.c sarray.c selector.c my_sendmsg.c \
+ NXConstStr.m Object.m Protocol.m
+
+HDRS= encoding.h hash.h list.h objc-api.h objc.h sarray.h typedstream.h \
+ NXConstStr.h Object.h Protocol.h
+
+CFLAGS+= -I${GCCDIR}/objc -I${GCCDIR}
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${HDRS:S;^;${GCCDIR}/objc/;} ${DESTDIR}/usr/include/objc
+
+my_objects.c: objects.c
+ sed -e '/\.\.\/tconfig.h/d' < ${GCCDIR}/objc/objects.c > my_objects.c
+
+my_sendmsg.c: sendmsg.c
+ sed -e '/\.\.\/tconfig.h/d' < ${GCCDIR}/objc/sendmsg.c > my_sendmsg.c
+
+CLEANFILES+= my_objects.c my_sendmsg.c
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libreadline/COPYING b/gnu/lib/libreadline/COPYING
new file mode 100644
index 0000000..1bb82d1
--- /dev/null
+++ b/gnu/lib/libreadline/COPYING
@@ -0,0 +1,257 @@
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+The Free Software Foundation has exempted Bash from the requirement of
+Paragraph 2c of the General Public License. This is to say, there is
+no requirement for Bash to print a notice when it is started
+interactively in the usual way. We made this exception because users
+and standards expect shells not to print such messages. This
+exception applies to any program that serves as a shell and that is
+based primarily on Bash as opposed to other GNU software.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+at the mercy of those companies. By contrast, our 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. The
+General Public License applies to the Free Software Foundation's
+software and to any other program whose authors commit to using it.
+You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Specifically, the General Public License is designed to make
+sure that you have the freedom to give away or sell copies of free
+software, 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 a 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 tell them 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.
+
+ 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 Agreement 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 work containing the
+Program or a portion of it, either verbatim or with modifications. Each
+licensee is addressed as "you".
+
+ 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
+General Public License and to the absence of any warranty; and give any
+other recipients of the Program a copy of this General Public License
+along with the Program. You may charge a fee for the physical act of
+transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+it, and copy and distribute such modifications under the terms of Paragraph
+1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual 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 General
+ Public License.
+
+ d) 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.
+
+Mere aggregation of another independent work with the Program (or its
+derivative) on a volume of a storage or distribution medium does not bring
+the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+it, under Paragraph 2) in object code or executable form under the terms of
+Paragraphs 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
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+Source code for a work means the preferred form of the work for making
+modifications to it. For an executable file, complete source code means
+all the source code for all modules it contains; but, as a special
+exception, it need not include source code for modules which are standard
+libraries that accompany the operating system on which the executable
+file runs, or for standard header files or definitions files that
+accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+Program except as expressly provided under this General Public License.
+Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+the Program is void, and will automatically terminate your rights to use
+the Program under this License. However, parties who have received
+copies, or rights to use copies, from you under this General Public
+License will not have their licenses terminated so long as such parties
+remain in full compliance.
+
+ 5. By copying, distributing or modifying 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.
+
+ 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.
+
+ 7. 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 the 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
+the license, you may choose any version ever published by the Free Software
+Foundation.
+
+ 8. 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
+
+ 9. 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.
+
+ 10. 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 humanity, 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, 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) 19xx 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 a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/gnu/lib/libreadline/ChangeLog b/gnu/lib/libreadline/ChangeLog
new file mode 100644
index 0000000..1cf0c00
--- /dev/null
+++ b/gnu/lib/libreadline/ChangeLog
@@ -0,0 +1,403 @@
+Tue Mar 23 14:36:51 1993 Brian Fox (bfox@eos.crseo.ucsb.edu)
+
+ * readline.c (rl_copy): Changed name to rl_copy_text.
+
+Mon Mar 22 19:16:05 1993 Brian Fox (bfox@eos.crseo.ucsb.edu)
+
+ * dispose_cmd.c, several other files. Declare dispose_xxx () as
+ "void".
+
+ * builtins/hashcom.h: Make declarations of hashed_filenames be
+ "extern" to keep the SGI compiler happy.
+
+ * readline.c (rl_initialize_everything): Assign values to
+ out_stream and in_stream immediately, since
+ output_character_function () can be called before
+ readline_internal () is called.
+
+Tue Dec 8 09:30:56 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (rl_init_terminal) Set PC from BC, not from *buffer.
+
+Mon Nov 30 09:35:47 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (invoking_keyseqs_in_map, rl_parse_and_bind) Allow
+ backslash to quote characters, such as backslash, double quote,
+ and space. Backslash quotes all character indiscriminately.
+
+ * funmap.c (vi_keymap) Fix type in "vi-replace" declaration.
+
+Fri Nov 20 10:55:05 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (init_terminal_io, rl_prep_terminal): FINALLY!
+ Declare and use termcap variable `ospeed' when setting up terminal
+ parameters.
+
+Thu Oct 8 08:53:07 1992 Brian J. Fox (bfox@helios)
+
+ * Makefile, this directory: Include (as links to the canonical
+ sources), tilde.c, tilde.h, posixstat.h and xmalloc.c.
+
+Tue Sep 29 13:07:21 1992 Brian J. Fox (bfox@helios)
+
+ * readline.c (init_terminal_io) Don't set arrow keys if the key
+ sequences that represent them are already set.
+
+ * readline.c (rl_function_of_keyseq) New function returns the first
+ function (or macro) found while searching a key sequence.
+
+Mon Sep 28 00:34:04 1992 Brian J. Fox (bfox@helios)
+
+ * readline.c (LibraryVersion) New static char * contains current
+ version number. Version is at 2.0.
+
+ * readline.c (rl_complete_internal): Incorporated clean changes
+ from gilmore (gnu@cygnus.com) to support quoted substrings within
+ completion functions.
+
+ * readline.c (many locations) Added support for the _GO32_,
+ whatever that is. Patches supplied by Cygnus, typed in by hand,
+ with cleanups.
+
+Sun Aug 16 12:46:24 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (init_terminal_io): Find out the values of the keypad
+ arrows and bind them to appropriate RL functions if present.
+
+Mon Aug 10 18:13:24 1992 Brian Fox (bfox@cubit)
+
+ * history.c (stifle_history): A negative argument to stifle
+ becomes zero.
+
+Tue Jul 28 09:28:41 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (rl_variable_bind): New local structure describes
+ booleans by name and address; code in rl_variable_bind () looks at
+ structure to set simple variables.
+
+ * parens.c (rl_insert_close): New variable rl_blink_matching_paren
+ is non-zero if we want to blink the matching open when a close is
+ inserted. If FD_SET is defined, rl_blink_matching_paren defaults
+ to 1, else 0. If FD_SET is not defined, and
+ rl_blink_matching_paren is non-zero, the close character(s) are/is
+ simply inserted.
+
+Wed Jul 22 20:03:59 1992 Brian Fox (bfox@cubit)
+
+ * history.c, readline.c, vi_mode.c: Cause the functions strchr ()
+ and strrchr () to be used instead of index () and rindex ()
+ throughout the source.
+
+Mon Jul 13 11:34:07 1992 Brian Fox (bfox@cubit)
+
+ * readline.c: (rl_variable_bind) New variable "meta-flag" if "on"
+ means force the use of the 8th bit as Meta bit. Internal variable
+ is called meta_flag.
+
+Thu Jul 9 10:37:56 1992 Brian Fox (bfox@cubit)
+
+ * history.c (get_history_event) Change INDEX to LOCAL_INDEX. If
+ compiling for the shell, allow shell metacharacters to separate
+ history tokens as they would for shell tokens.
+
+Sat Jul 4 19:29:12 1992 Brian Fox (bfox@cubit)
+
+ * vi_keymap.c: According to Posix, TAB self-inserts instead of
+ doing completion.
+
+ * vi_mode.c: (rl_vi_yank_arg) Enter VI insert mode after yanking
+ an arg from the previous line.
+
+ * search.c: New file takes over vi style searching and implements
+ non-incremental searching the history.
+
+ Makefile: Add search.c and search.o.
+
+ funmap.c: Add names for non-incremental-forward-search-history and
+ non-incremental-reverse-search-history.
+
+ readline.h: Add extern definitions for non-incremental searching.
+
+ vi_mode.c: Remove old search code; add calls to code in search.c.
+
+Fri Jul 3 10:36:33 1992 Brian Fox (bfox@cubit)
+
+ * readline.c (rl_delete_horizontal_space); New function deletes
+ all whitespace surrounding point.
+
+ funmap.c: Add "delete-horizontal-space".
+ emacs_keymap.c: Put rl_delete_horizontal_space () on M-\.
+
+ * readline.c (rl_set_signals, rl_clear_signals); New function
+ rl_set_sighandler () is either defined in a Posix way (if
+ HAVE_POSIX_SIGNALS is defined) or in a BSD way. Function is
+ called from rl_set_signals () and rl_clear_signals ().
+
+Fri May 8 12:50:15 1992 Brian Fox (bfox@cubit)
+
+ * readline.c: (readline_default_bindings) Do comparisons with
+ _POSIX_VDISABLE casted to `unsigned char'. Change tty characters
+ to be unsigned char.
+
+Thu Apr 30 12:36:35 1992 Brian Fox (bfox@cubit)
+
+ * readline.c: (rl_getc) Handle "read would block" error on
+ non-blocking IO streams.
+
+ * readline.c: (rl_signal_handler): Unblock only the signal that we
+ have caught, not all signals.
+
+Sun Feb 23 03:33:09 1992 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: Many functions. Use only the macros META_CHAR and
+ UNMETA to deal with meta characters. Prior to this, we used
+ numeric values and tests.
+
+ * readline.c (rl_complete_internal) Report exactly the number of
+ possible completions, not the number + 1.
+
+ * vi_mode.c (rl_do_move) Do not change the cursor position when
+ using `cw' or `cW'.
+
+ * vi_mode.c (rl_vi_complete) Enter insert mode after completing
+ with `*' or `\'.
+
+Fri Feb 21 05:58:18 1992 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (rl_dispatch) Increment rl_key_sequence_length for
+ meta characters that map onto ESC map.
+
+Mon Feb 10 01:41:35 1992 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * history.c (history_do_write) Build a buffer of all of the lines
+ to write and write them in one fell swoop (lower overhead than
+ calling write () for each line). Suggested by Peter Ho.
+
+ * readline.c: Include hbullx20 as well as hpux for determining
+ USGr3ness.
+
+ * readline.c (rl_unix_word_rubout) As per the "Now REMEMBER"
+ comment, pass arguments to rl_kill_text () in the correct order to
+ preserve prepending and appending of killed text.
+
+ * readline.c (rl_search_history) malloc (), realloc (), and free
+ () SEARCH_STRING so that there are no static limits on searching.
+
+ * vi_mode.c (rl_vi_subst) Don't forget to end the undo group.
+
+Fri Jan 31 14:51:02 1992 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (rl_signal_handler): Zero the current history entry's
+ pointer after freeing the undo_list when SIGINT received.
+ Reformat a couple of functions.
+
+Sat Jan 25 13:47:35 1992 Brian Fox (bfox at bears)
+
+ * readline.c (parser_if): free () TNAME after use.
+
+Tue Jan 21 01:01:35 1992 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (rl_redisplay) and (rl_character_len): Display
+ Control characters as "^c" and Meta characters as "\234", instead
+ of "C-C" and "M-C".
+
+Sun Dec 29 10:59:00 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (init_terminal_io) Default to environment variables
+ LINES and COLUMNS before termcap entry values. If all else fails,
+ then assume 80x24 terminal.
+
+Sat Dec 28 16:33:11 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: If this machine is USG and it is hpux, then define
+ USGr3.
+
+ * history.c: Cosmetic fixes.
+
+Thu Nov 21 00:10:12 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * vi_mode.c: (rl_do_move) Place cursor at end of line, never at
+ next to last character.
+
+Thu Nov 14 05:08:01 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * history.c (get_history_event) Non-anchored searches can have a
+ return index of greater than zero from get_history_event ().
+
+Fri Nov 1 07:02:13 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (rl_translate_keyseq) Make C-? translate to RUBOUT
+ unconditionally.
+
+Mon Oct 28 11:34:52 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c; Use Posix directory routines and macros.
+
+ * funmap.c; Add entry for call-last-kbd-macro.
+
+ * readline.c (rl_prep_term); Use system EOF character on POSIX
+ systems also.
+
+Thu Oct 3 16:19:53 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c; Make a distinction between having a TERMIOS tty
+ driver, and having POSIX signal handling. You might one without
+ the other. New defines used HAVE_POSIX_SIGNALS, and
+ TERMIOS_TTY_DRIVER.
+
+Tue Jul 30 22:37:26 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: rl_getc () If a call to read () returns without an
+ error, but with zero characters, the file is empty, so return EOF.
+
+Thu Jul 11 20:58:38 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: (rl_get_next_history, rl_get_previous_history)
+ Reallocate the buffer space if the line being moved to is longer
+ the the current space allocated. Amazing that no one has found
+ this bug until now.
+
+Sun Jul 7 02:37:05 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c:(rl_parse_and_bind) Allow leading whitespace.
+ Make sure TERMIO and TERMIOS systems treat CR and NL
+ disctinctly.
+
+Tue Jun 25 04:09:27 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: Rework parsing conditionals to pay attention to the
+ prior states of the conditional stack. This makes $if statements
+ work correctly.
+
+Mon Jun 24 20:45:59 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: support for displaying key binding information
+ includes the functions rl_list_funmap_names (),
+ invoking_keyseqs_in_map (), rl_invoking_keyseqs (),
+ rl_dump_functions (), and rl_function_dumper ().
+
+ funmap.c: support for same includes rl_funmap_names ().
+
+ readline.c, funmap.c: no longer define STATIC_MALLOC. However,
+ update both version of xrealloc () to handle a null pointer.
+
+Thu Apr 25 12:03:49 1991 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * vi_mode.c (rl_vi_fword, fWord, etc. All functions use
+ the macro `isident()'. Fixed movement bug which prevents
+ continious movement through the text.
+
+Fri Jul 27 16:47:01 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (parser_if) Allow "$if term=foo" construct.
+
+Wed May 23 16:10:33 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c (rl_dispatch) Correctly remember the last command
+ executed. Fixed typo in username_completion_function ().
+
+Mon Apr 9 19:55:48 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: username_completion_function (); For text passed in
+ with a leading `~', remember that this could be a filename (after
+ it is completed).
+
+Thu Apr 5 13:44:24 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: rl_search_history (): Correctly handle case of an
+ unfound search string, but a graceful exit (as with ESC).
+
+ * readline.c: rl_restart_output (); The Apollo passes the address
+ of the file descriptor to TIOCSTART, not the descriptor itself.
+
+Tue Mar 20 05:38:55 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * readline.c: rl_complete (); second call in a row causes possible
+ completions to be listed.
+
+ * readline.c: rl_redisplay (), added prompt_this_line variable
+ which is the first character character following \n in prompt.
+
+Sun Mar 11 04:32:03 1990 Brian Fox (bfox at gnuwest.fsf.org)
+
+ * Signals are now supposedly handled inside of SYSV compilation.
+
+Wed Jan 17 19:24:09 1990 Brian Fox (bfox at sbphy.ucsb.edu)
+
+ * history.c: history_expand (); fixed overwriting memory error,
+ added needed argument to call to get_history_event ().
+
+Thu Jan 11 10:54:04 1990 Brian Fox (bfox at sbphy.ucsb.edu)
+
+ * readline.c: added mark_modified_lines to control the
+ display of an asterisk on modified history lines. Also
+ added a user variable called mark-modified-lines to the
+ `set' command.
+
+Thu Jan 4 10:38:05 1990 Brian Fox (bfox at sbphy.ucsb.edu)
+
+ * readline.c: start_insert (). Only use IC if we don't have an im
+ capability.
+
+Fri Sep 8 09:00:45 1989 Brian Fox (bfox at aurel)
+
+ * readline.c: rl_prep_terminal (). Only turn on 8th bit
+ as meta-bit iff the terminal is not using parity.
+
+Sun Sep 3 08:57:40 1989 Brian Fox (bfox at aurel)
+
+ * readline.c: start_insert (). Uses multiple
+ insertion call in cases where that makes sense.
+
+ rl_insert (). Read type-ahead buffer for additional
+ keys that are bound to rl_insert, and insert them
+ all at once. Make insertion of single keys given
+ with an argument much more efficient.
+
+Tue Aug 8 18:13:57 1989 Brian Fox (bfox at aurel)
+
+ * readline.c: Changed handling of EOF. readline () returns
+ (char *)EOF or consed string. The EOF character is read from the
+ tty, or if the tty doesn't have one, defaults to C-d.
+
+ * readline.c: Added support for event driven programs.
+ rl_event_hook is the address of a function you want called
+ while Readline is waiting for input.
+
+ * readline.c: Cleanup time. Functions without type declarations
+ do not use return with a value.
+
+ * history.c: history_expand () has new variable which is the
+ characters to ignore immediately following history_expansion_char.
+
+Sun Jul 16 08:14:00 1989 Brian Fox (bfox at aurel)
+
+ * rl_prep_terminal ()
+ BSD version turns off C-s, C-q, C-y, C-v.
+
+ * readline.c -- rl_prep_terminal ()
+ SYSV version hacks readline_echoing_p.
+ BSD version turns on passing of the 8th bit for the duration
+ of reading the line.
+
+Tue Jul 11 06:25:01 1989 Brian Fox (bfox at aurel)
+
+ * readline.c: new variable rl_tilde_expander.
+ 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.
+
+ * readline.h - new file chardefs.h
+ Separates things that only readline.c needs from the standard
+ header file publishing interesting things about readline.
+
+ * readline.c:
+ readline_default_bindings () now looks at terminal chararacters
+ and binds those as well.
+
+Wed Jun 28 20:20:51 1989 Brian Fox (bfox at aurel)
+
+ * Made readline and history into independent libraries.
+
diff --git a/gnu/lib/libreadline/Makefile b/gnu/lib/libreadline/Makefile
new file mode 100644
index 0000000..de4e976
--- /dev/null
+++ b/gnu/lib/libreadline/Makefile
@@ -0,0 +1,26 @@
+# $Id: Makefile,v 1.22 1996/08/30 02:13:06 peter Exp $
+
+
+CFLAGS+= -I${.CURDIR} -DVOID_SIGHANDLER -DHAVE_CONFIG_H \
+ -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1
+
+LIB= readline
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 0
+SRCS+= readline.c funmap.c keymaps.c vi_mode.c parens.c \
+ rltty.c complete.c bind.c isearch.c display.c signals.c \
+ history.c search.c tilde.c xmalloc.c
+HEADERS= history.h readline.h keymaps.h chardefs.h tilde.h
+MAN3= readline.3
+DPADD+= $(LIBTERMCAP)
+LDADD+= -ltermcap
+
+SUBDIR+= doc
+
+beforeinstall:
+.for i in ${HEADERS}
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/$i \
+ ${DESTDIR}/usr/include/readline
+.endfor
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libreadline/README b/gnu/lib/libreadline/README
new file mode 100644
index 0000000..131471c
--- /dev/null
+++ b/gnu/lib/libreadline/README
@@ -0,0 +1,6 @@
+This is the distribution of the Gnu Readline library. See the file
+STANDALONE for a description of the #defines that can be passed via
+the makefile to build readline on different systems.
+
+The file rlconf.h contains defines that enable and disable certain
+readline features.
diff --git a/gnu/lib/libreadline/README.8bit b/gnu/lib/libreadline/README.8bit
new file mode 100644
index 0000000..56da6e2
--- /dev/null
+++ b/gnu/lib/libreadline/README.8bit
@@ -0,0 +1,6 @@
+If you want 8-bit clean version, put
+ set convert-meta off
+ set output-meta on
+in your ~/.inputrc file
+
+ache@astral.msk.su
diff --git a/gnu/lib/libreadline/STANDALONE b/gnu/lib/libreadline/STANDALONE
new file mode 100644
index 0000000..c1387f3
--- /dev/null
+++ b/gnu/lib/libreadline/STANDALONE
@@ -0,0 +1,31 @@
+This is a description of C preprocessor defines that readline accepts.
+Most are passed in from the parent `make'; e.g. from the bash source
+directory.
+
+NO_SYS_FILE <sys/file.h> is not present
+HAVE_UNISTD_H <unistd.h> exists
+HAVE_STDLIB_H <stdlib.h> exists
+HAVE_VARARGS_H <varargs.h> exists and is usable
+HAVE_STRING_H <string.h> exists
+HAVE_ALLOCA_H <alloca.h> exists and is needed for alloca()
+HAVE_ALLOCA alloca(3) or a define for it exists
+PRAGMA_ALLOCA use of alloca() requires a #pragma, as in AIX 3.x
+VOID_SIGHANDLER signal handlers are void functions
+HAVE_DIRENT_H <dirent.h> exists and is usable
+HAVE_SYS_PTEM_H <sys/ptem.h> exists
+HAVE_SYS_PTE_H <sys/pte.h> exists
+HAVE_SYS_STREAM_H <sys/stream.h> exists
+
+System-specific options:
+
+GWINSZ_IN_SYS_IOCTL need to include <sys/ioctl.h> for TIOCGWINSZ
+HAVE_GETPW_DECLS the getpw* functions are declared in <pwd.h> and cannot
+ be redeclared without compiler errors
+HAVE_STRCASECMP the strcasecmp and strncasecmp functions are available
+
+USG Running a variant of System V
+USGr3 Running System V.3
+XENIX_22 Xenix 2.2
+Linux Linux
+CRAY running a recent version of Cray UNICOS
+SunOS4 Running SunOS 4.x
diff --git a/gnu/lib/libreadline/VERSION b/gnu/lib/libreadline/VERSION
new file mode 100644
index 0000000..a74bd28
--- /dev/null
+++ b/gnu/lib/libreadline/VERSION
@@ -0,0 +1 @@
+Readline from bash 1.14.5 + local fixes
diff --git a/gnu/lib/libreadline/ansi_stdlib.h b/gnu/lib/libreadline/ansi_stdlib.h
new file mode 100644
index 0000000..52339da
--- /dev/null
+++ b/gnu/lib/libreadline/ansi_stdlib.h
@@ -0,0 +1,41 @@
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (_STDLIB_H_)
+#define _STDLIB_H_ 1
+
+/* String conversion functions. */
+extern int atoi ();
+extern long int atol ();
+
+/* Memory allocation functions. */
+extern char *malloc ();
+extern char *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/gnu/lib/libreadline/bind.c b/gnu/lib/libreadline/bind.c
new file mode 100644
index 0000000..8821599
--- /dev/null
+++ b/gnu/lib/libreadline/bind.c
@@ -0,0 +1,1487 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+#include <signal.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#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"
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+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 int _rl_complete_show_all;
+#if defined (PAREN_MATCHING)
+extern int rl_blink_matching_paren;
+#endif /* PAREN_MATCHING */
+#if defined (VISIBLE_STATS)
+extern int rl_visible_stats;
+#endif /* VISIBLE_STATS */
+extern int rl_complete_with_tilde_expansion;
+extern int rl_completion_query_items;
+#if defined (VI_MODE)
+extern char *rl_vi_comment_begin;
+#endif
+
+extern int rl_explicit_arg;
+extern int rl_editing_mode;
+extern unsigned short _rl_parsing_conditionalized_out;
+extern Keymap _rl_keymap;
+
+extern char *possible_control_prefixes[], *possible_meta_prefixes[];
+
+extern char **rl_funmap_names ();
+
+/* Forward declarations */
+void rl_set_keymap_from_edit_mode ();
+
+static int glean_key_from_name ();
+
+#if defined (HAVE_STRCASECMP)
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#else
+static int stricmp (), strnicmp ();
+#endif
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* **************************************************************** */
+/* */
+/* Binding keys */
+/* */
+/* **************************************************************** */
+
+/* rl_add_defun (char *name, Function *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. */
+rl_add_defun (name, function, key)
+ char *name;
+ Function *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;
+ Function *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;
+ 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;
+ Function *function;
+ Keymap map;
+{
+ int result;
+ Keymap 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, (Function *)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, (Function *)NULL, 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. */
+rl_set_key (keyseq, function, map)
+ char *keyseq;
+ Function *function;
+ Keymap map;
+{
+ return (rl_generic_bind (ISFUNC, keyseq, 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. */
+rl_macro_bind (keyseq, macro, map)
+ 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, &macro_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. */
+rl_generic_bind (type, keyseq, data, map)
+ int type;
+ char *keyseq, *data;
+ Keymap map;
+{
+ char *keys;
+ int keys_len;
+ register int i;
+
+ /* If no keys to bind to, exit right away. */
+ if (!keyseq || !*keyseq)
+ {
+ if (type == ISMACR)
+ free (data);
+ return -1;
+ }
+
+ keys = 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++)
+ {
+ int ic = (int) ((unsigned char)keys[i]);
+
+ 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)
+ {
+ if (map[ic].type == ISMACR)
+ free ((char *)map[ic].function);
+
+ map[ic].type = ISKMAP;
+ map[ic].function = KEYMAP_TO_FUNCTION (rl_make_bare_keymap());
+ }
+ map = FUNCTION_TO_KEYMAP (map, ic);
+ }
+ else
+ {
+ if (map[ic].type == ISMACR)
+ free ((char *)map[ic].function);
+
+ map[ic].function = KEYMAP_TO_FUNCTION (data);
+ map[ic].type = type;
+ }
+ }
+ 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. */
+rl_translate_keyseq (seq, array, len)
+ char *seq, *array;
+ int *len;
+{
+ register int i, c, l = 0;
+
+ for (i = 0; c = seq[i]; i++)
+ {
+ if (c == '\\')
+ {
+ c = seq[++i];
+
+ if (!c)
+ break;
+
+ if (((c == 'C' || c == 'M') && seq[i + 1] == '-') ||
+ (c == 'e'))
+ {
+ /* Handle special case of backwards define. */
+ if (strncmp (&seq[i], "C-\\M-", 5) == 0)
+ {
+ array[l++] = ESC;
+ i += 5;
+ array[l++] = CTRL (to_upper (seq[i]));
+ if (!seq[i])
+ i--;
+ continue;
+ }
+
+ switch (c)
+ {
+ case 'M':
+ i++;
+ array[l++] = ESC;
+ break;
+
+ case 'C':
+ i += 2;
+ /* Special hack for C-?... */
+ if (seq[i] == '?')
+ array[l++] = RUBOUT;
+ else
+ array[l++] = CTRL (to_upper (seq[i]));
+ break;
+
+ case 'e':
+ array[l++] = ESC;
+ }
+
+ continue;
+ }
+ }
+ array[l++] = c;
+ }
+
+ *len = l;
+ array[l] = '\0';
+ return (0);
+}
+
+/* Return a pointer to the function that STRING represents.
+ If STRING doesn't have a matching function, then a NULL pointer
+ is returned. */
+Function *
+rl_named_function (string)
+ char *string;
+{
+ register int i;
+
+ rl_initialize_funmap ();
+
+ for (i = 0; funmap[i]; i++)
+ if (stricmp (funmap[i]->name, string) == 0)
+ return (funmap[i]->function);
+ return ((Function *)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). */
+Function *
+rl_function_of_keyseq (keyseq, map, type)
+ char *keyseq;
+ Keymap map;
+ int *type;
+{
+ register int i;
+
+ if (!map)
+ map = _rl_keymap;
+
+ for (i = 0; keyseq && keyseq[i]; i++)
+ {
+ int 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 ((Function *) NULL);
+}
+
+/* The last key bindings file read. */
+static char *last_readline_init_file = (char *)NULL;
+
+/* Re-read the current keybindings file. */
+rl_re_read_init_file (count, ignore)
+ int count, ignore;
+{
+ int r;
+ r = rl_read_init_file ((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)
+ char *filename;
+{
+ register int i;
+ char *buffer, *openname, *line, *end;
+ struct stat finfo;
+ int file;
+
+ /* Default the filename. */
+ if (!filename)
+ {
+ filename = last_readline_init_file;
+ if (!filename)
+ filename = getenv ("INPUTRC");
+ if (!filename)
+ filename = DEFAULT_INPUTRC;
+ }
+
+ if (!*filename)
+ filename = DEFAULT_INPUTRC;
+
+ openname = tilde_expand (filename);
+
+ if ((stat (openname, &finfo) < 0) ||
+ (file = open (openname, O_RDONLY, 0666)) < 0)
+ {
+ free (openname);
+ return (errno);
+ }
+ else
+ free (openname);
+
+ if (filename != last_readline_init_file)
+ {
+ if (last_readline_init_file)
+ free (last_readline_init_file);
+
+ last_readline_init_file = savestring (filename);
+ }
+
+ /* Read the file into BUFFER. */
+ buffer = (char *)xmalloc ((int)finfo.st_size + 1);
+ i = read (file, buffer, finfo.st_size);
+ close (file);
+
+ if (i != finfo.st_size)
+ return (errno);
+
+ /* Loop over the lines in the file. Lines that start with `#' are
+ comments; all other lines are commands for readline initialization. */
+ line = buffer;
+ end = buffer + finfo.st_size;
+ while (line < end)
+ {
+ /* Find the end of this line. */
+ for (i = 0; line + i != end && line[i] != '\n'; i++);
+
+ /* 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;
+ }
+ free (buffer);
+ return (0);
+}
+
+/* **************************************************************** */
+/* */
+/* Parser Directives */
+/* */
+/* **************************************************************** */
+
+/* Conditionals. */
+
+/* Calling programs set this to have their argv[0]. */
+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 = 0;
+static int if_stack_size = 0;
+
+/* 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 && 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. */
+ if ((stricmp (args + 5, tname) == 0) ||
+ (stricmp (args + 5, rl_terminal_name) == 0))
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+
+ free (tname);
+ }
+#if defined (VI_MODE)
+ else if (strnicmp (args, "mode=", 5) == 0)
+ {
+ int mode;
+
+ if (stricmp (args + 5, "emacs") == 0)
+ mode = emacs_mode;
+ else if (stricmp (args + 5, "vi") == 0)
+ mode = vi_mode;
+ else
+ mode = no_mode;
+
+ if (mode == rl_editing_mode)
+ _rl_parsing_conditionalized_out = 0;
+ else
+ _rl_parsing_conditionalized_out = 1;
+ }
+#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 (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)
+ {
+ /* Error message? */
+ 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
+ {
+ /* *** What, no error message? *** */
+ }
+ return 0;
+}
+
+/* Associate textual names with actual functions. */
+static struct {
+ char *name;
+ Function *function;
+} parser_directives [] = {
+ { "if", parser_if },
+ { "endif", parser_endif },
+ { "else", parser_else },
+ { (char *)0x0, (Function *)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 (stricmp (directive, parser_directives[i].name) == 0)
+ {
+ (*parser_directives[i].function) (args);
+ return (0);
+ }
+
+ /* *** Should an error message be output? */
+ return (1);
+}
+
+static int substring_member_of_array ();
+
+/* 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. */
+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;
+ }
+ }
+
+ /* 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 (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++];
+ int passc = 0;
+
+ for (; 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 = xmalloc (1 + strlen (string));
+ register int j, k = 0;
+ int passc = 0;
+
+ for (j = 1; 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, possible_control_prefixes))
+ key = CTRL (to_upper (key));
+
+ if (substring_member_of_array (string, possible_meta_prefixes))
+ key = META (key);
+
+ /* Temporary. Handle old-style keyname with macro-binding. */
+ if (*funname == '\'' || *funname == '"')
+ {
+ char seq[2];
+ int fl = strlen (funname);
+
+ seq[0] = key; seq[1] = '\0';
+ if (fl && funname[fl - 1] == *funname)
+ funname[fl - 1] = '\0';
+
+ rl_macro_bind (seq, &funname[1], _rl_keymap);
+ }
+#if defined (PREFIX_META_HACK)
+ /* Ugly, but working hack to keep prefix-meta around. */
+ else if (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. */
+
+static struct {
+ char *name;
+ int *value;
+} boolean_varlist [] = {
+ { "horizontal-scroll-mode", &_rl_horizontal_scroll_mode },
+ { "mark-modified-lines", &_rl_mark_modified_lines },
+ { "meta-flag", &_rl_meta_flag },
+#if defined (PAREN_MATCHING)
+ { "blink-matching-paren", &rl_blink_matching_paren },
+#endif
+ { "convert-meta", &_rl_convert_meta_chars_to_ascii },
+ { "show-all-if-ambiguous", &_rl_complete_show_all },
+ { "output-meta", &_rl_output_meta_chars },
+#if defined (VISIBLE_STATS)
+ { "visible-stats", &rl_visible_stats },
+#endif /* VISIBLE_STATS */
+ { "expand-tilde", &rl_complete_with_tilde_expansion },
+ { (char *)NULL, (int *)NULL }
+};
+
+rl_variable_bind (name, value)
+ char *name, *value;
+{
+ register int i;
+
+ /* Check for simple variables first. */
+ for (i = 0; boolean_varlist[i].name; i++)
+ {
+ if (stricmp (name, boolean_varlist[i].name) == 0)
+ {
+ /* A variable is TRUE if the "value" is "on", "1" or "". */
+ if ((!*value) ||
+ (stricmp (value, "On") == 0) ||
+ (value[0] == '1' && value[1] == '\0'))
+ *boolean_varlist[i].value = 1;
+ else
+ *boolean_varlist[i].value = 0;
+ return 0;
+ }
+ }
+
+ /* Not a boolean variable, so check for specials. */
+
+ /* Editing mode change? */
+ if (stricmp (name, "editing-mode") == 0)
+ {
+ if (strnicmp (value, "vi", 2) == 0)
+ {
+#if defined (VI_MODE)
+ _rl_keymap = vi_insertion_keymap;
+ rl_editing_mode = vi_mode;
+#endif /* VI_MODE */
+ }
+ else if (strnicmp (value, "emacs", 5) == 0)
+ {
+ _rl_keymap = emacs_standard_keymap;
+ rl_editing_mode = emacs_mode;
+ }
+ }
+
+ /* Comment string change? */
+ else if (stricmp (name, "comment-begin") == 0)
+ {
+#if defined (VI_MODE)
+ if (*value)
+ {
+ if (rl_vi_comment_begin)
+ free (rl_vi_comment_begin);
+
+ rl_vi_comment_begin = savestring (value);
+ }
+#endif /* VI_MODE */
+ }
+ else if (stricmp (name, "completion-query-items") == 0)
+ {
+ int nval = 100;
+ if (*value)
+ {
+ nval = atoi (value);
+ if (nval < 0)
+ nval = 0;
+ }
+ rl_completion_query_items = nval;
+ }
+ else if (stricmp (name, "keymap") == 0)
+ {
+ Keymap kmap;
+ kmap = rl_get_keymap_by_name (value);
+ if (kmap)
+ rl_set_keymap (kmap);
+ }
+ else if (stricmp (name, "bell-style") == 0)
+ {
+ if (!*value)
+ _rl_bell_preference = AUDIBLE_BELL;
+ else
+ {
+ if (stricmp (value, "none") == 0 || stricmp (value, "off") == 0)
+ _rl_bell_preference = NO_BELL;
+ else if (stricmp (value, "audible") == 0 || stricmp (value, "on") == 0)
+ _rl_bell_preference = AUDIBLE_BELL;
+ else if (stricmp (value, "visible") == 0)
+ _rl_bell_preference = VISIBLE_BELL;
+ }
+ }
+ else if (stricmp (name, "prefer-visible-bell") == 0)
+ {
+ /* Backwards compatibility. */
+ if (*value && (stricmp (value, "on") == 0 ||
+ (*value == '1' && !value[1])))
+ _rl_bell_preference = VISIBLE_BELL;
+ else
+ _rl_bell_preference = AUDIBLE_BELL;
+ }
+
+ return 0;
+}
+
+/* Return the character which matches NAME.
+ For example, `Space' returns ' '. */
+
+typedef struct {
+ 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 (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 {
+ 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)
+ char *name;
+{
+ register int i;
+
+ for (i = 0; keymap_names[i].name; i++)
+ if (strcmp (name, keymap_names[i].name) == 0)
+ return (keymap_names[i].map);
+ return ((Keymap) 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 */
+}
+
+/* **************************************************************** */
+/* */
+/* 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 (count, ignore)
+ int count, ignore;
+{
+ register int i;
+ 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);
+}
+
+/* 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)
+ Function *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 < 128; 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 = (char *)xmalloc (5);
+
+ if (CTRL_CHAR (key))
+ sprintf (keyname, "\\C-%c", 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';
+ }
+
+ if (result_index + 2 > result_size)
+ result = (char **) xrealloc
+ (result, (result_size += 10) * sizeof (char *));
+
+ result[result_index++] = keyname;
+ result[result_index] = (char *)NULL;
+ }
+ break;
+
+ case ISKMAP:
+ {
+ char **seqs = (char **)NULL;
+
+ /* 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));
+
+ if (seqs)
+ {
+ register int i;
+
+ for (i = 0; seqs[i]; i++)
+ {
+ char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
+
+ if (key == ESC)
+ sprintf (keyname, "\\e");
+ else if (CTRL_CHAR (key))
+ sprintf (keyname, "\\C-%c", 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 = (char **) xrealloc
+ (result, (result_size += 10) * 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)
+ Function *function;
+{
+ return (rl_invoking_keyseqs_in_map (function, _rl_keymap));
+}
+
+/* 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;
+{
+ rl_function_dumper (rl_explicit_arg);
+ rl_on_new_line ();
+ return (0);
+}
+
+/* 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;
+ char **names;
+ char *name;
+
+ names = rl_funmap_names ();
+
+ fprintf (rl_outstream, "\n");
+
+ for (i = 0; name = names[i]; i++)
+ {
+ Function *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);
+ }
+ }
+ }
+}
+
+/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. */
+void
+_rl_bind_if_unbound (keyseq, default_func)
+ char *keyseq;
+ Function *default_func;
+{
+ Function *func;
+
+ if (keyseq)
+ {
+ func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
+ if (!func || func == rl_do_lowercase_version)
+ rl_set_key (keyseq, default_func, _rl_keymap);
+ }
+}
+
+/* **************************************************************** */
+/* */
+/* String Utility Functions */
+/* */
+/* **************************************************************** */
+
+static char *strindex ();
+
+/* Return non-zero if any members of ARRAY are a substring in STRING. */
+static int
+substring_member_of_array (string, array)
+ char *string, **array;
+{
+ while (*array)
+ {
+ if (strindex (string, *array))
+ return (1);
+ array++;
+ }
+ return (0);
+}
+
+#if !defined (HAVE_STRCASECMP)
+/* Whoops, Unix doesn't have strnicmp. */
+
+/* Compare at most COUNT characters from string1 to string2. Case
+ doesn't matter. */
+static int
+strnicmp (string1, string2, count)
+ char *string1, *string2;
+ int count;
+{
+ register char ch1, ch2;
+
+ while (count)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+ if (to_upper(ch1) == to_upper(ch2))
+ count--;
+ else
+ break;
+ }
+ return (count);
+}
+
+/* strcmp (), but caseless. */
+static int
+stricmp (string1, string2)
+ char *string1, *string2;
+{
+ register char ch1, ch2;
+
+ while (*string1 && *string2)
+ {
+ ch1 = *string1++;
+ ch2 = *string2++;
+ if (to_upper(ch1) != to_upper(ch2))
+ return (1);
+ }
+ return (*string1 - *string2);
+}
+#endif /* !HAVE_STRCASECMP */
+
+/* Determine if s2 occurs in s1. If so, return a pointer to the
+ match in s1. The compare is case insensitive. */
+static char *
+strindex (s1, s2)
+ register char *s1, *s2;
+{
+ register int i, l = strlen (s2);
+ register int len = strlen (s1);
+
+ for (i = 0; (len - i) >= l; i++)
+ if (strnicmp (s1 + i, s2, l) == 0)
+ return (s1 + i);
+ return ((char *)NULL);
+}
diff --git a/gnu/lib/libreadline/chardefs.h b/gnu/lib/libreadline/chardefs.h
new file mode 100644
index 0000000..8c92811
--- /dev/null
+++ b/gnu/lib/libreadline/chardefs.h
@@ -0,0 +1,122 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _CHARDEFS_H
+#define _CHARDEFS_H
+
+#include <ctype.h>
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* HAVE_STRING_H */
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#ifdef CTRL
+#undef CTRL
+#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)
+#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) to_upper(((c)|control_character_bit))
+
+/* Old versions
+#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
+#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
+#define digit_p(c) ((c) >= '0' && (c) <= '9')
+*/
+
+#define lowercase_p(c) (islower(c))
+#define uppercase_p(c) (isupper(c))
+#define digit_p(x) (isdigit (x))
+
+#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
+
+/* Old versions
+# define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
+# define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
+*/
+
+#ifndef to_upper
+# define to_upper(c) (islower(c) ? toupper(c) : (c))
+# define to_lower(c) (isupper(c) ? tolower(c) : (c))
+#endif
+
+#ifndef digit_value
+#define digit_value(x) ((x) - '0')
+#endif
+
+#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/gnu/lib/libreadline/complete.c b/gnu/lib/libreadline/complete.c
new file mode 100644
index 0000000..f219877
--- /dev/null
+++ b/gnu/lib/libreadline/complete.c
@@ -0,0 +1,1459 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include <pwd.h>
+#if defined (USG) && !defined (HAVE_GETPW_DECLS)
+extern struct passwd *getpwent ();
+#endif /* USG && !HAVE_GETPW_DECLS */
+
+/* ISC systems don't define getpwent() if _POSIX_SOURCE is defined. */
+#if defined (isc386) && defined (_POSIX_SOURCE)
+# if defined (__STDC__)
+extern struct passwd *getpwent (void);
+# else
+extern struct passwd *getpwent ();
+# endif /* !__STDC__ */
+#endif /* isc386 && _POSIX_SOURCE */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+
+/* Possible values for do_replace in rl_complete_internal. */
+#define NO_MATCH 0
+#define SINGLE_MATCH 1
+#define MULT_MATCH 2
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+extern char *tilde_expand ();
+extern char *rl_copy_text ();
+
+extern Function *rl_last_func;
+extern int rl_editing_mode;
+extern int screenwidth;
+
+/* Forward declarations for functions defined and used in this file. */
+char *filename_completion_function ();
+char **completion_matches ();
+
+static int compare_strings ();
+static char *rl_strpbrk ();
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* 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. */
+Function *rl_directory_completion_hook = (Function *)NULL;
+
+/* Non-zero means readline completion functions perform tilde expansion. */
+int rl_complete_with_tilde_expansion = 0;
+
+/* If non-zero, non-unique completions always show the list of matches. */
+int _rl_complete_show_all = 0;
+
+#if defined (VISIBLE_STATS)
+# if !defined (X_OK)
+# define X_OK 1
+# endif
+
+static int stat_char ();
+
+/* 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 */
+
+/* **************************************************************** */
+/* */
+/* Completion matching, from readline's point of view. */
+/* */
+/* **************************************************************** */
+
+/* Pointer to the generator function for completion_matches ().
+ NULL means to use filename_entry_function (), the default filename
+ completer. */
+Function *rl_completion_entry_function = (Function *)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. */
+CPPFunction *rl_attempted_completion_function = (CPPFunction *)NULL;
+
+/* Non-zero means to suppress normal filename completion after the
+ user-specified completion function has been called. */
+int rl_attempted_completion_over = 0;
+
+/* Local variable states what happened during the last completion attempt. */
+static int completion_changed_buffer = 0;
+
+/* Complete the word at or before point. You have supplied the function
+ that does the initial simple matching selection algorithm (see
+ completion_matches ()). The default is to do filename completion. */
+
+rl_complete (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ 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 (). */
+rl_possible_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ return (rl_complete_internal ('?'));
+}
+
+rl_insert_completions (ignore, invoking_key)
+ int ignore, invoking_key;
+{
+ return (rl_complete_internal ('*'));
+}
+
+/* The user must press "y" or "n". Non-zero return means "y" pressed. */
+get_y_or_n ()
+{
+ int c;
+
+ for (;;)
+ {
+ c = rl_read_key ();
+ if (c == 'y' || c == 'Y' || c == ' ')
+ return (1);
+ if (c == 'n' || c == 'N' || c == RUBOUT)
+ return (0);
+ if (c == ABORT_CHAR)
+ rl_abort ();
+ ding ();
+ }
+}
+
+/* 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;
+
+/* 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\"\\'`@$><=" */
+char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{(";
+
+/* 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. */
+char *rl_completer_word_break_characters = (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. */
+char *rl_completer_quote_characters = (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. */
+char *rl_special_prefixes = (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_word_break_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. */
+Function *rl_ignore_some_completions_function = (Function *)NULL;
+
+#if defined (SHELL)
+/* A function to strip quotes that are not protected by backquotes. It
+ allows single quotes to appear within double quotes, and vice versa.
+ It should be smarter. It's fairly shell-specific, hence the SHELL
+ definition wrapper. */
+static char *
+_delete_quotes (text)
+ char *text;
+{
+ char *ret, *p, *r;
+ int l, quoted;
+
+ l = strlen (text);
+ ret = xmalloc (l + 1);
+ for (quoted = 0, p = text, r = ret; p && *p; p++)
+ {
+ /* Allow backslash-quoted characters to pass through unscathed. */
+ if (*p == '\\')
+ continue;
+ /* Close quote. */
+ if (quoted && *p == quoted)
+ {
+ quoted = 0;
+ continue;
+ }
+ /* Open quote. */
+ if (quoted == 0 && (*p == '\'' || *p == '"'))
+ {
+ quoted = *p;
+ continue;
+ }
+ *r++ = *p;
+ }
+ *r = '\0';
+ return ret;
+}
+#endif /* SHELL */
+
+/* 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. */
+static char *
+printable_part (pathname)
+ char *pathname;
+{
+ char *temp = (char *)NULL;
+
+ if (rl_filename_completion_desired)
+ temp = strrchr (pathname, '/');
+
+ if (!temp)
+ return (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 1 if we printed an extension character, 0 if not. */
+#define PUTX(c) \
+ if (CTRL_CHAR (c)) \
+ { \
+ putc ('^', rl_outstream); \
+ putc (UNCTRL (c), rl_outstream); \
+ } \
+ else if (c == RUBOUT) \
+ { \
+ putc ('^', rl_outstream); \
+ putc ('?', rl_outstream); \
+ } \
+ else \
+ putc (c, rl_outstream)
+
+static int
+print_filename (to_print, full_pathname)
+ char *to_print, *full_pathname;
+{
+#if !defined (VISIBLE_STATS)
+ char *s;
+
+ for (s = to_print; *s; s++)
+ {
+ PUTX (*s);
+ }
+ return 0;
+#else
+ char *s, c, *new_full_pathname;
+ int extension_char = 0, 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';
+
+ s = tilde_expand (full_pathname);
+ if (rl_directory_completion_hook)
+ (*rl_directory_completion_hook) (&s);
+
+ slen = strlen (s);
+ tlen = strlen (to_print);
+ new_full_pathname = 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);
+ return (extension_char != 0);
+ }
+ else
+ return 0;
+#endif /* VISIBLE_STATS */
+}
+
+/* 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. */
+rl_complete_internal (what_to_do)
+ int what_to_do;
+{
+ char **matches;
+ Function *our_func;
+ int start, scan, end, delimiter = 0, pass_next;
+ char *text, *saved_line_buffer;
+ char *replacement;
+ char quote_char = '\0';
+ int found_quote = 0;
+
+ if (rl_line_buffer)
+ saved_line_buffer = savestring (rl_line_buffer);
+ else
+ saved_line_buffer = (char *)NULL;
+
+ if (rl_completion_entry_function)
+ our_func = rl_completion_entry_function;
+ else
+ our_func = (Function *)filename_completion_function;
+
+ /* Only the completion entry function can change these. */
+ rl_filename_completion_desired = 0;
+ rl_filename_quoting_desired = 1;
+
+ /* We now look backwards for the start of a filename/variable word. */
+ end = rl_point;
+
+ if (rl_point)
+ {
+ 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;
+ }
+
+ if (rl_line_buffer[scan] == '\\')
+ {
+ pass_next = 1;
+ found_quote |= 4;
+ 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 |= 1;
+ else if (quote_char == '"')
+ found_quote |= 2;
+ }
+ }
+ }
+
+ if (rl_point == end && quote_char == '\0')
+ {
+ int quoted = 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. */
+ while (--rl_point)
+ {
+ scan = rl_line_buffer[rl_point];
+
+ if (strchr (rl_completer_word_break_characters, scan) == 0)
+ continue;
+
+#if defined (SHELL)
+ /* Don't let word break characters in quoted substrings break
+ words for the completer. */
+ if (found_quote && char_is_quoted (rl_line_buffer, rl_point))
+ continue;
+#endif /* SHELL */
+
+ /* 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 defined (SHELL)
+ if ((found_quote == 0 || char_is_quoted (rl_line_buffer, rl_point) == 0) &&
+ strchr (rl_completer_word_break_characters, scan))
+#else
+ if (strchr (rl_completer_word_break_characters, scan))
+#endif
+ {
+ /* If the character that caused the word break was a quoting
+ character, then remember it as the delimiter. */
+ if (strchr ("\"'", 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 || strchr (rl_special_prefixes, scan) == 0)
+ rl_point++;
+ }
+ }
+
+ /* At this point, we know we have an open quote if quote_char != '\0'. */
+ start = rl_point;
+ rl_point = end;
+ text = rl_copy_text (start, end);
+
+ /* 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;
+ our_func = (Function *)NULL;
+ goto after_usual_completion;
+ }
+ }
+
+#if defined (SHELL)
+ /* Beware -- we're stripping the quotes here. Do this only if we know
+ we are doing filename completion. */
+ if (found_quote && our_func == (Function *)filename_completion_function)
+ {
+ /* delete single and double quotes */
+ replacement = _delete_quotes (text);
+ free (text);
+ text = replacement;
+ replacement = (char *)0;
+ }
+#endif /* SHELL */
+
+ matches = completion_matches (text, our_func);
+
+ after_usual_completion:
+ free (text);
+
+ if (!matches)
+ ding ();
+ else
+ {
+ register int i;
+ int should_quote;
+
+ /* 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)
+ {
+ char *lowest_common;
+ int j, newlen = 0;
+ char dead_slot;
+ char **temp_array;
+
+ /* Sort the items. */
+ /* It is safe to sort this array, because the lowest common
+ denominator found in matches[0] will remain in place. */
+ for (i = 0; matches[i]; i++)
+ ;
+ /* Try sorting 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 *), compare_strings);
+
+ /* Remember the lowest common denominator for it may be unique. */
+ lowest_common = savestring (matches[0]);
+
+ for (i = 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]);
+ free (matches);
+
+ matches = temp_array;
+
+ /* Place the lowest common denominator back in [0]. */
+ matches[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 (matches[0], matches[1]) == 0)
+ {
+ free (matches[1]);
+ matches[1] = (char *)NULL;
+ }
+ }
+
+ switch (what_to_do)
+ {
+ case TAB:
+ case '!':
+ /* 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 &&
+ our_func == (Function *)filename_completion_function)
+ {
+ (void)(*rl_ignore_some_completions_function)(matches);
+ if (matches == 0 || matches[0] == 0)
+ {
+ if (matches)
+ free (matches);
+ ding ();
+ return;
+ }
+ }
+
+ /* 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 = matches[0];
+
+ should_quote = matches[0] && rl_completer_quote_characters &&
+ rl_filename_completion_desired &&
+ rl_filename_quoting_desired;
+
+ if (should_quote)
+#if defined (SHELL)
+ should_quote = should_quote && (!quote_char || quote_char == '"');
+#else
+ should_quote = should_quote && !quote_char;
+#endif
+
+ if (should_quote)
+ {
+ int do_replace;
+
+ do_replace = NO_MATCH;
+
+ /* 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. If the common prefix should
+ not be checked, add !matches[1] to the if clause. */
+ should_quote = rl_strpbrk (matches[0], rl_completer_word_break_characters) != 0;
+#if defined (SHELL)
+ should_quote = should_quote || rl_strpbrk (matches[0], "#$`?*[!") != 0;
+#endif
+
+ if (should_quote)
+ do_replace = matches[1] ? MULT_MATCH : SINGLE_MATCH;
+
+ if (do_replace != NO_MATCH)
+ {
+#if defined (SHELL)
+ /* Quote the replacement, since we found an
+ embedded word break character in a potential
+ match. */
+ char *rtext, *mtext;
+ int rlen;
+ extern char *double_quote (); /* in builtins/common.c */
+
+ /* If DO_REPLACE == MULT_MATCH, it means that there is
+ more than one match. In this case, we do not add
+ the closing quote or attempt to perform tilde
+ expansion. If DO_REPLACE == SINGLE_MATCH, we try
+ to perform tilde expansion, because double quotes
+ inhibit tilde expansion by the shell. */
+
+ mtext = matches[0];
+ if (mtext[0] == '~' && do_replace == SINGLE_MATCH)
+ mtext = tilde_expand (matches[0]);
+ rtext = double_quote (mtext);
+ if (mtext != matches[0])
+ free (mtext);
+
+ rlen = strlen (rtext);
+ replacement = xmalloc (rlen + 1);
+ /* If we're completing on a quoted string where the user
+ has already supplied the opening quote, we don't want
+ the quote in the replacement text, and we reset
+ QUOTE_CHAR to 0 to avoid an extra closing quote. */
+ if (quote_char == '"')
+ {
+ strcpy (replacement, rtext + 1);
+ rlen--;
+ quote_char = 0;
+ }
+ else
+ strcpy (replacement, rtext);
+ if (do_replace == MULT_MATCH)
+ replacement[rlen - 1] = '\0';
+ free (rtext);
+#else /* !SHELL */
+ /* Found an embedded word break character in a potential
+ match, so we need to prepend a quote character if we
+ are replacing the completion string. */
+ replacement = xmalloc (strlen (matches[0]) + 2);
+ quote_char = *rl_completer_quote_characters;
+ *replacement = quote_char;
+ strcpy (replacement + 1, matches[0]);
+#endif /* SHELL */
+ }
+ }
+
+ if (replacement)
+ {
+ rl_begin_undo_group ();
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ rl_insert_text (replacement);
+ rl_end_undo_group ();
+ if (replacement != matches[0])
+ free (replacement);
+ }
+
+ /* If there are more matches, ring the bell to indicate.
+ If this was the only match, and we are hacking files,
+ check the file to see if it was a directory. If so,
+ 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 == '!')
+ goto display_matches; /* XXX */
+ else if (rl_editing_mode != vi_mode)
+ ding (); /* There are other matches remaining. */
+ }
+ else
+ {
+ char temp_string[4];
+ int temp_string_index = 0;
+
+ if (quote_char)
+ temp_string[temp_string_index++] = quote_char;
+
+ temp_string[temp_string_index++] = delimiter ? delimiter : ' ';
+ temp_string[temp_string_index++] = '\0';
+
+ if (rl_filename_completion_desired)
+ {
+ struct stat finfo;
+ char *filename = tilde_expand (matches[0]);
+
+ if ((stat (filename, &finfo) == 0) && S_ISDIR (finfo.st_mode))
+ {
+ if (rl_line_buffer[rl_point] != '/')
+ rl_insert_text ("/");
+ }
+ else
+ {
+ if (rl_point == rl_end)
+ rl_insert_text (temp_string);
+ }
+ free (filename);
+ }
+ else
+ {
+ if (rl_point == rl_end)
+ rl_insert_text (temp_string);
+ }
+ }
+ break;
+
+ case '*':
+ {
+ int i = 1;
+
+ rl_begin_undo_group ();
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ if (matches[1])
+ {
+ while (matches[i])
+ {
+ rl_insert_text (matches[i++]);
+ rl_insert_text (" ");
+ }
+ }
+ else
+ {
+ rl_insert_text (matches[0]);
+ rl_insert_text (" ");
+ }
+ rl_end_undo_group ();
+ }
+ break;
+
+ case '?':
+ {
+ int len, count, limit, max;
+ int j, k, l;
+
+ /* Handle simple case first. What if there is only one answer? */
+ if (!matches[1])
+ {
+ char *temp;
+
+ temp = printable_part (matches[0]);
+ crlf ();
+ print_filename (temp, matches[0]);
+ crlf ();
+ goto restart;
+ }
+
+ /* There is more than one answer. Find out how many there are,
+ and find out what the maximum printed length of a single entry
+ is. */
+ display_matches:
+ for (max = 0, i = 1; matches[i]; i++)
+ {
+ char *temp;
+ int name_length;
+
+ temp = printable_part (matches[i]);
+ name_length = strlen (temp);
+
+ if (name_length > max)
+ max = name_length;
+ }
+
+ len = i - 1;
+
+ /* If there are many items, then ask the user if she
+ really wants to see them all. */
+ if (len >= rl_completion_query_items)
+ {
+ crlf ();
+ fprintf (rl_outstream,
+ "There are %d possibilities. Do you really", len);
+ crlf ();
+ fprintf (rl_outstream, "wish to see them all? (y or n)");
+ fflush (rl_outstream);
+ if (!get_y_or_n ())
+ {
+ crlf ();
+ goto restart;
+ }
+ }
+
+ /* How many items of MAX length can we fit in the screen window? */
+ max += 2;
+ limit = screenwidth / max;
+ if (limit != 1 && (limit * max == screenwidth))
+ limit--;
+
+ /* Avoid a possible floating exception. If max > 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)
+ qsort (matches + 1, len - 1, sizeof (char *), compare_strings);
+
+ /* Print the sorted items, up-and-down alphabetically, like
+ ls might. */
+ crlf ();
+
+ for (i = 1; i <= count; i++)
+ {
+ for (j = 0, l = i; j < limit; j++)
+ {
+ if (l > len || !matches[l])
+ break;
+ else
+ {
+ char *temp;
+ int printed_length;
+
+ temp = printable_part (matches[l]);
+ printed_length = strlen (temp);
+ printed_length += print_filename (temp, matches[l]);
+
+ if (j + 1 < limit)
+ {
+ for (k = 0; k < max - printed_length; k++)
+ putc (' ', rl_outstream);
+ }
+ }
+ l += count;
+ }
+ crlf ();
+ }
+ restart:
+
+ rl_on_new_line ();
+ }
+ break;
+
+ default:
+ fprintf (stderr, "\r\nreadline: bad value for what_to_do in rl_complete\n");
+ abort ();
+ }
+
+ for (i = 0; matches[i]; i++)
+ free (matches[i]);
+ free (matches);
+ }
+
+ /* Check to see if the line has changed through all of this manipulation. */
+ if (saved_line_buffer)
+ {
+ if (strcmp (rl_line_buffer, saved_line_buffer) != 0)
+ completion_changed_buffer = 1;
+ else
+ completion_changed_buffer = 0;
+
+ free (saved_line_buffer);
+ }
+ return 0;
+}
+
+#if defined (VISIBLE_STATS)
+/* Return the character which best describes FILENAME.
+ `@' for symbolic links
+ `/' for directories
+ `*' for executables
+ `=' for sockets */
+static int
+stat_char (filename)
+ char *filename;
+{
+ struct stat finfo;
+ int character, r;
+
+#if 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_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 */
+ else if (S_ISREG (finfo.st_mode))
+ {
+ if (access (filename, X_OK) == 0)
+ character = '*';
+ }
+ return (character);
+}
+#endif /* VISIBLE_STATS */
+
+/* Stupid comparison routine for qsort () ing strings. */
+static int
+compare_strings (s1, s2)
+ char **s1, **s2;
+{
+ int result;
+
+ result = **s1 - **s2;
+ if (result == 0)
+ result = strcmp (*s1, *s2);
+
+ return result;
+}
+
+/* A completion function for usernames.
+ TEXT contains a partial username preceded by a random
+ character (usually `~'). */
+char *
+username_completion_function (text, state)
+ int state;
+ char *text;
+{
+#if defined (__GO32__)
+ return (char *)NULL;
+#else /* !__GO32__ */
+ static char *username = (char *)NULL;
+ static struct passwd *entry;
+ static int namelen, first_char, first_char_loc;
+
+ if (!state)
+ {
+ if (username)
+ free (username);
+
+ first_char = *text;
+
+ if (first_char == '~')
+ first_char_loc = 1;
+ else
+ first_char_loc = 0;
+
+ 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)
+ break;
+ else if ((username[0] == entry->pw_name[0]) &&
+ (strncmp (username, entry->pw_name, namelen) == 0))
+ break;
+ }
+
+ if (!entry)
+ {
+ endpwent ();
+ return ((char *)NULL);
+ }
+ else
+ {
+ char *value = 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 /* !__GO32__ */
+}
+
+/* **************************************************************** */
+/* */
+/* Completion */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means that case is not significant in completion. */
+int completion_case_fold = 0;
+
+/* 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 **
+completion_matches (text, entry_function)
+ char *text;
+ CPFunction *entry_function;
+{
+ /* Number of slots in match_list. */
+ int match_list_size;
+
+ /* The list of matches. */
+ char **match_list =
+ (char **)xmalloc (((match_list_size = 10) + 1) * sizeof (char *));
+
+ /* Number of matches actually found. */
+ int matches = 0;
+
+ /* Temporary string binder. */
+ char *string;
+
+ 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)
+ {
+ register int i = 1;
+ int low = 100000; /* Count of max-matched characters. */
+
+ /* If only one match, just use that. */
+ if (matches == 1)
+ {
+ match_list[0] = match_list[1];
+ match_list[1] = (char *)NULL;
+ }
+ else
+ {
+ /* Otherwise, compare each member of the list with
+ the next, finding out where they stop matching. */
+
+ while (i < matches)
+ {
+ register int c1, c2, si;
+
+ if (completion_case_fold)
+ {
+ for (si = 0;
+ (c1 = to_lower(match_list[i][si])) &&
+ (c2 = to_lower(match_list[i + 1][si]));
+ si++)
+ if (c1 != c2) break;
+ }
+ else
+ {
+ for (si = 0;
+ (c1 = match_list[i][si]) &&
+ (c2 = match_list[i + 1][si]);
+ si++)
+ if (c1 != c2) break;
+ }
+
+ if (low > si) low = si;
+ i++;
+ }
+ match_list[0] = xmalloc (low + 1);
+ strncpy (match_list[0], match_list[1], low);
+ match_list[0][low] = '\0';
+ }
+ }
+ else /* There were no matches. */
+ {
+ free (match_list);
+ match_list = (char **)NULL;
+ }
+ return (match_list);
+}
+
+/* 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 *
+filename_completion_function (text, state)
+ int state;
+ char *text;
+{
+ static DIR *directory;
+ static char *filename = (char *)NULL;
+ static char *dirname = (char *)NULL;
+ static char *users_dirname = (char *)NULL;
+ static int filename_len;
+
+ struct dirent *entry = (struct dirent *)NULL;
+
+ /* If we don't have any state, then do some initialization. */
+ if (!state)
+ {
+ char *temp;
+
+ if (dirname) free (dirname);
+ if (filename) free (filename);
+ if (users_dirname) free (users_dirname);
+
+ filename = savestring (text);
+ if (!*text) text = ".";
+ dirname = savestring (text);
+
+ temp = strrchr (dirname, '/');
+
+ if (temp)
+ {
+ strcpy (filename, ++temp);
+ *temp = '\0';
+ }
+ else
+ strcpy (dirname, ".");
+
+ /* 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);
+ {
+ char *temp_dirname;
+ int replace_dirname;
+
+ temp_dirname = tilde_expand (dirname);
+ free (dirname);
+ dirname = temp_dirname;
+
+ replace_dirname = 0;
+ if (rl_directory_completion_hook)
+ replace_dirname = (*rl_directory_completion_hook) (&dirname);
+ if (replace_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<WILD>/te<TAB>. 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. */
+
+ while (directory && (entry = readdir (directory)))
+ {
+ /* Special case for no filename.
+ All entries except "." and ".." match. */
+ if (!filename_len)
+ {
+ if ((strcmp (entry->d_name, ".") != 0) &&
+ (strcmp (entry->d_name, "..") != 0))
+ break;
+ }
+ else
+ {
+ /* Otherwise, if these match up to the length of filename, then
+ it is a match. */
+ if ((entry->d_name[0] == filename[0]) &&
+ (((int)D_NAMLEN (entry)) >= filename_len) &&
+ (strncmp (filename, entry->d_name, filename_len) == 0))
+ break;
+ }
+ }
+
+ if (!entry)
+ {
+ 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
+ {
+ char *temp;
+
+ /* dirname && (strcmp (dirname, ".") != 0) */
+ if (dirname && (dirname[0] != '.' || dirname[1]))
+ {
+ if (rl_complete_with_tilde_expansion && *users_dirname == '~')
+ {
+ int dirlen = strlen (dirname);
+ temp = xmalloc (2 + dirlen + D_NAMLEN (entry));
+ strcpy (temp, dirname);
+ /* Canonicalization cuts off any final slash present. We need
+ to add it back. */
+ if (dirname[dirlen - 1] != '/')
+ {
+ temp[dirlen] = '/';
+ temp[dirlen + 1] = '\0';
+ }
+ }
+ else
+ {
+ temp = xmalloc (1 + strlen (users_dirname) + D_NAMLEN (entry));
+ strcpy (temp, users_dirname);
+ }
+
+ strcat (temp, entry->d_name);
+ }
+ else
+ temp = (savestring (entry->d_name));
+
+ return (temp);
+ }
+}
+
+/* A function for simple tilde expansion. */
+int
+rl_tilde_expand (ignore, key)
+ int ignore, key;
+{
+ register int start, end;
+ char *homedir;
+
+ end = rl_point;
+ start = end - 1;
+
+ if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
+ {
+ homedir = tilde_expand ("~");
+ goto insert;
+ }
+ 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]) && 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] == '~')
+ {
+ char *temp;
+ int len;
+
+ len = end - start + 1;
+ temp = xmalloc (len + 1);
+ strncpy (temp, rl_line_buffer + start, len);
+ temp[len] = '\0';
+ homedir = tilde_expand (temp);
+ free (temp);
+
+ insert:
+ rl_begin_undo_group ();
+ rl_delete_text (start, end + 1);
+ rl_point = start;
+ rl_insert_text (homedir);
+ rl_end_undo_group ();
+ }
+
+ return (0);
+}
+
+/* Find the first occurrence in STRING1 of any character from STRING2.
+ Return a pointer to the character in STRING1. */
+static char *
+rl_strpbrk (string1, string2)
+ char *string1, *string2;
+{
+ register char *scan;
+
+ for (; *string1; string1++)
+ {
+ for (scan = string2; *scan; scan++)
+ {
+ if (*string1 == *scan)
+ {
+ return (string1);
+ }
+ }
+ }
+ return ((char *)NULL);
+}
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)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 ();
+}
+#endif /* STATIC_MALLOC */
diff --git a/gnu/lib/libreadline/config.h b/gnu/lib/libreadline/config.h
new file mode 100644
index 0000000..6c3b267
--- /dev/null
+++ b/gnu/lib/libreadline/config.h
@@ -0,0 +1,71 @@
+/* config.h. Generated automatically by configure. */
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+#ifndef _RL_CONFIG_H
+#define _RL_CONFIG_H
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca.h and it should be used (not Ultrix). */
+/* #undef HAVE_ALLOCA_H */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if you do not have strings.h, index, bzero, etc.. */
+/* #undef USG */
+
+/* Define if your system defines TIOCGWINSZ in sys/ioctl.h. */
+#define GWINSZ_IN_SYS_IOCTL 1
+
+/* #undef HAVE_GETPW_DECLS */
+/* #undef NO_SYS_FILE */
+
+/* Define if you have strcasecmp. */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the <alloca.h> header file. */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/pte.h> header file. */
+/* #undef HAVE_SYS_PTE_H */
+
+/* Define if you have the <sys/ptem.h> header file. */
+/* #undef HAVE_SYS_PTEM_H */
+
+/* Define if you have the <sys/stream.h> header file. */
+/* #undef HAVE_SYS_STREAM_H */
+
+/* Define if you have the <termcap.h> header file. */
+#define HAVE_TERMCAP_H 1
+
+/* Define if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the <varargs.h> header file. */
+#define HAVE_VARARGS_H 1
+
+#endif
diff --git a/gnu/lib/libreadline/display.c b/gnu/lib/libreadline/display.c
new file mode 100644
index 0000000..daf736c
--- /dev/null
+++ b/gnu/lib/libreadline/display.c
@@ -0,0 +1,1276 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+/* Global and pseudo-global variables and functions
+ imported from readline.c. */
+extern char *rl_prompt;
+extern int readline_echoing_p;
+extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
+/* Termcap variables. */
+extern char *term_up, *term_dc, *term_cr, *term_IC;
+extern int screenheight, screenwidth, screenchars;
+extern int terminal_can_insert, term_xn;
+
+extern void _rl_output_some_chars ();
+extern int _rl_output_character_function ();
+
+extern int _rl_output_meta_chars;
+extern int _rl_horizontal_scroll_mode;
+extern int _rl_mark_modified_lines;
+extern int _rl_prefer_visible_bell;
+
+/* Pseudo-global functions (local to the readline library) exported
+ by this file. */
+void _rl_move_cursor_relative (), _rl_output_some_chars ();
+void _rl_move_vert ();
+
+static void update_line (), clear_to_eol (), space_to_eol ();
+static void delete_chars (), insert_some_chars ();
+
+extern char *xmalloc (), *xrealloc ();
+
+/* 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. */
+
+/* Global variables declared here. */
+/* What YOU turn on when you have handled all redisplay yourself. */
+int rl_display_fixed = 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 = 0;
+
+/* 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 = 0;
+
+/* Default and initial buffer size. Can grow. */
+static int line_size = 1024;
+
+static char *last_prompt_string = (char *)NULL;
+static char *local_prompt, *local_prompt_prefix;
+static int visible_length, prefix_length;
+
+/* The number of invisible characters in the line currently being
+ displayed on the screen. */
+static int visible_wrap_offset = 0;
+
+/* 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 = 0;
+
+/* 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. */
+
+/* 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)
+ char *pmt;
+ int *lp;
+{
+ char *r, *ret, *p;
+ int l, rl, ignoring;
+
+ /* Short-circuit if we can. */
+ if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
+ {
+ r = savestring (pmt);
+ if (lp)
+ *lp = strlen (r);
+ return r;
+ }
+
+ l = pmt ? strlen (pmt) : 0;
+ r = ret = xmalloc (l + 1);
+
+ for (rl = ignoring = 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;
+ continue;
+ }
+ else
+ {
+ *r++ = *p;
+ if (!ignoring)
+ rl++;
+ }
+ }
+
+ *r = '\0';
+ if (lp)
+ *lp = rl;
+ 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
+ * visible_length = number of visible characters in local_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. */
+ if (local_prompt)
+ free (local_prompt);
+ if (local_prompt_prefix)
+ free (local_prompt_prefix);
+ local_prompt = local_prompt_prefix = (char *)0;
+
+ if (prompt == 0 || *prompt == '\0')
+ return (0);
+
+ p = strrchr (prompt, '\n');
+ if (!p)
+ {
+ /* The prompt is only one line. */
+ local_prompt = expand_prompt (prompt, &visible_length);
+ local_prompt_prefix = (char *)0;
+ return (visible_length);
+ }
+ else
+ {
+ /* The prompt spans multiple lines. */
+ t = ++p;
+ local_prompt = expand_prompt (p, &visible_length);
+ 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, &prefix_length);
+ *t = c;
+ return (prefix_length);
+ }
+}
+
+/* Basic redisplay algorithm. */
+void
+rl_redisplay ()
+{
+ register int in, out, c, linenum;
+ register char *line = invisible_line;
+ int c_pos = 0, inv_botlin = 0, wrap_offset, wrap_column;
+ char *prompt_this_line;
+
+ if (!readline_echoing_p)
+ return;
+
+ if (!rl_display_prompt)
+ rl_display_prompt = "";
+
+ if (!invisible_line)
+ {
+ visible_line = xmalloc (line_size);
+ invisible_line = xmalloc (line_size);
+ line = invisible_line;
+ for (in = 0; in < line_size; in++)
+ {
+ visible_line[in] = 0;
+ invisible_line[in] = 1;
+ }
+ rl_on_new_line ();
+ }
+
+ /* Draw the line into the buffer. */
+ c_pos = -1;
+
+ /* Mark the line as modified or not. We only do this for history
+ lines. */
+ out = 0;
+ 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)
+ {
+ 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)
+ strncpy (line + out, local_prompt, local_len);
+ out += local_len;
+ line[out] = '\0';
+ wrap_offset = local_len - 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++;
+ if (forced_display)
+ _rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
+ }
+
+ pmtlen = strlen (prompt_this_line);
+ strncpy (line + out, prompt_this_line, pmtlen);
+ out += pmtlen;
+ line[out] = '\0';
+ wrap_offset = 0;
+ }
+
+ for (in = 0; in < rl_end; in++)
+ {
+ c = (unsigned char)rl_line_buffer[in];
+
+ if (out + 8 >= line_size) /* XXX - 8 for \t */
+ {
+ line_size *= 2;
+ visible_line = xrealloc (visible_line, line_size);
+ invisible_line = xrealloc (invisible_line, line_size);
+ line = invisible_line;
+ }
+
+ if (in == rl_point)
+ c_pos = out;
+
+ if (META_CHAR (c))
+ {
+ if (_rl_output_meta_chars == 0)
+ {
+ sprintf (line + out, "\\%o", c);
+ out += 4;
+ }
+ else
+ line[out++] = c;
+ }
+#if defined (DISPLAY_TABS)
+ else if (c == '\t')
+ {
+ register int newout = (out | (int)7) + 1;
+ while (out < newout)
+ line[out++] = ' ';
+ }
+#endif
+ else if (c < ' ')
+ {
+ line[out++] = '^';
+ line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */
+ }
+ else if (c == 127)
+ {
+ line[out++] = '^';
+ line[out++] = '?';
+ }
+ else
+ line[out++] = c;
+ }
+ line[out] = '\0';
+ if (c_pos < 0)
+ c_pos = out;
+
+ /* C_POS == position in buffer where 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 && term_up && *term_up)
+ {
+ int total_screen_chars = screenchars;
+ int nleft, cursor_linenum, 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. I'll fix this in a minute. */
+ if (out >= total_screen_chars)
+ out = total_screen_chars - 1;
+
+ /* Number of screen lines to display. The first line wraps at
+ (screenwidth + wrap_offset) chars, the rest of the lines have
+ screenwidth chars. */
+ nleft = out - wrap_offset + term_xn - 1;
+ inv_botlin = (nleft > 0) ? nleft / screenwidth : 0;
+
+ /* The first line is at character position 0 in the buffer. The
+ second and subsequent lines start at N * screenwidth, offset by
+ OFFSET. OFFSET is wrap_offset for the invisible line and
+ visible_wrap_offset for the line currently displayed. */
+
+#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
+#define L_OFFSET(n, offset) ((n) > 0 ? ((n) * screenwidth) + (offset) : 0)
+#define VIS_CHARS(line) &visible_line[L_OFFSET((line), visible_wrap_offset)]
+#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
+#define INV_LINE(line) &invisible_line[L_OFFSET((line), wrap_offset)]
+
+ /* 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,
+ screenwidth + W_OFFSET(linenum, visible_wrap_offset),
+ screenwidth + W_OFFSET(linenum, wrap_offset),
+ 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. */
+ if (linenum == 0 &&
+ inv_botlin == 0 &&
+ (wrap_offset > visible_wrap_offset) &&
+ (_rl_last_c_pos < visible_first_line_len))
+ {
+ nleft = screenwidth + wrap_offset - _rl_last_c_pos;
+ if (nleft)
+ 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) ? screenwidth : 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);
+ clear_to_eol
+ ((linenum == _rl_vis_botlin) ? strlen (tt) : screenwidth);
+ }
+ }
+ _rl_vis_botlin = inv_botlin;
+
+ /* Move the cursor where it should be. */
+ /* Which line? */
+ nleft = c_pos - wrap_offset + term_xn - 1;
+ cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0;
+
+ /* 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 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. */
+ nleft = visible_length + wrap_offset;
+ if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
+ _rl_last_c_pos <= nleft && local_prompt)
+ {
+ if (term_cr)
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_output_some_chars (local_prompt, nleft);
+ _rl_last_c_pos = nleft;
+ }
+
+ /* Where on that line? And where does that line start
+ in the buffer? */
+ pos = L_OFFSET(cursor_linenum, wrap_offset);
+ /* nleft == number of characters in the line buffer between the
+ start of the line and the cursor position. */
+ nleft = c_pos - pos;
+
+ /* Since 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 backspace() directly. */
+ if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
+ {
+ backspace (_rl_last_c_pos - nleft);
+ _rl_last_c_pos = nleft;
+ }
+
+ 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 = 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 = 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 > 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 < 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 characters 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) + 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,
+ screenwidth + visible_wrap_offset,
+ 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 = screenwidth - t;
+ clear_to_eol (nleft);
+ }
+ visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset);
+ if (visible_first_line_len > screenwidth)
+ visible_first_line_len = screenwidth;
+
+ _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
+ last_lmargin = lmargin;
+ }
+ }
+ fflush (rl_outstream);
+
+ /* Swap visible and non-visible lines. */
+ {
+ char *temp = visible_line;
+ visible_line = invisible_line;
+ invisible_line = temp;
+ 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 handeled.
+
+ 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;
+{
+ register char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ int temp, lendiff, wsatend, od, nd;
+
+ /* 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 == screenwidth && term_xn && !_rl_horizontal_scroll_mode
+ && _rl_last_v_pos == current_line - 1)
+ {
+ 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. */
+ 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 */
+ ols = oe - 1; /* find last same */
+ nls = ne - 1;
+ while ((ols > ofd) && (nls > nfd) && (*ols == *nls))
+ {
+ if (*ols != ' ')
+ wsatend = 0;
+ ols--;
+ nls--;
+ }
+
+ if (wsatend)
+ {
+ ols = oe;
+ nls = ne;
+ }
+ else if (*ols != *nls)
+ {
+ if (*ols) /* don't step past the NUL */
+ ols++;
+ if (*nls)
+ nls++;
+ }
+
+ _rl_move_vert (current_line);
+
+ /* If this is the first line and there are invisible characters in the
+ prompt string, and the prompt string has not changed, then redraw
+ the entire prompt string. We can only do this reliably if the
+ terminal supports a `cr' capability.
+
+ This is more than just 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;
+ if (current_line == 0 && !_rl_horizontal_scroll_mode &&
+ lendiff > visible_length &&
+ _rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr)
+ {
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_output_some_chars (local_prompt, lendiff);
+ _rl_last_c_pos = lendiff;
+ }
+
+ _rl_move_cursor_relative (ofd - old, old);
+
+ /* if (len (new) > len (old)) */
+ lendiff = (nls - nfd) - (ols - ofd);
+
+ /* Insert (diff (len (old), len (new)) ch. */
+ temp = ne - nfd;
+ if (lendiff > 0)
+ {
+ /* 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 (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl))
+ {
+ /* If lendiff > visible_length and _rl_last_c_pos == 0 and
+ _rl_horizontal_scroll_mode == 1, inserting the characters with
+ term_IC or 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 <= visible_length))
+ {
+ insert_some_chars (nfd, lendiff);
+ _rl_last_c_pos += lendiff;
+ }
+ else
+ {
+ /* At the end of a line the characters do not have to
+ be "inserted". They can just be placed on the screen. */
+ _rl_output_some_chars (nfd, lendiff);
+ _rl_last_c_pos += lendiff;
+ }
+ /* 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);
+ _rl_last_c_pos += temp - lendiff;
+ }
+ }
+ else
+ {
+ /* cannot insert chars, write to EOL */
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += temp;
+ }
+ }
+ else /* Delete characters from line. */
+ {
+ /* If possible and inexpensive to use terminal deletion, then do so. */
+ if (term_dc && (2 * temp) >= -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)
+ lendiff = 0;
+
+ if (lendiff)
+ delete_chars (-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 += temp;
+ }
+ }
+ /* Otherwise, print over the existing material. */
+ else
+ {
+ if (temp > 0)
+ {
+ _rl_output_some_chars (nfd, temp);
+ _rl_last_c_pos += temp;
+ }
+ lendiff = (oe - old) - (ne - new);
+ if (term_xn && current_line < inv_botlin)
+ space_to_eol (lendiff);
+ else
+ clear_to_eol (lendiff);
+ }
+ }
+}
+
+/* Tell the update routines that we have moved onto a new (empty) line. */
+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;
+ return 0;
+}
+
+/* Actually update the display, period. */
+rl_forced_update_display ()
+{
+ if (visible_line)
+ {
+ register char *temp = visible_line;
+
+ while (*temp) *temp++ = '\0';
+ }
+ rl_on_new_line ();
+ forced_display++;
+ rl_redisplay ();
+ 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;
+ char *data;
+{
+ register int i;
+
+ /* If we don't have to do anything, then return. */
+ if (_rl_last_c_pos == new) return;
+
+ /* It may be faster to output a CR, and then move forwards instead
+ of moving backwards. */
+ /* i == current physical cursor position. */
+ i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
+ if (CR_FASTER (new, _rl_last_c_pos) || (term_xn && i == screenwidth))
+ {
+#if defined (__MSDOS__)
+ putc ('\r', rl_outstream);
+#else
+ tputs (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)
+ extern char *term_forward_char;
+
+ if (term_forward_char)
+ for (i = _rl_last_c_pos; i < new; i++)
+ tputs (term_forward_char, 1, _rl_output_character_function);
+ else
+ for (i = _rl_last_c_pos; 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 */
+ }
+ else if (_rl_last_c_pos != new)
+ backspace (_rl_last_c_pos - new);
+ _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 > screenheight)
+ return;
+
+#if defined (__GO32__)
+ {
+ int row, col;
+
+ ScreenGetCursor (&row, &col);
+ ScreenSetCursor ((row + to - _rl_last_v_pos), col);
+ }
+#else /* !__GO32__ */
+
+ if ((delta = to - _rl_last_v_pos) > 0)
+ {
+ for (i = 0; i < delta; i++)
+ putc ('\n', rl_outstream);
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_last_c_pos = 0;
+ }
+ else
+ { /* delta < 0 */
+ if (term_up && *term_up)
+ for (i = 0; i < -delta; i++)
+ tputs (term_up, 1, _rl_output_character_function);
+ }
+#endif /* !__GO32__ */
+ _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. */
+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 (c < 32 && c != '\t')
+#else
+ if (c < 32)
+#endif /* !DISPLAY_TABS */
+ {
+ fprintf (rl_outstream, "C-");
+ n += 2;
+ c += 64;
+ }
+
+ 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 */
+ }
+
+ return ((isprint (uc)) ? 1 : 2);
+}
+
+/* How to print things in the "echo-area". The prompt is treated as a
+ mini-modeline. */
+
+#if defined (HAVE_VARARGS_H)
+rl_message (va_alist)
+ va_dcl
+{
+ char *format;
+ va_list args;
+
+ va_start (args);
+ format = va_arg (args, char *);
+ vsprintf (msg_buf, format, args);
+ va_end (args);
+
+ rl_display_prompt = msg_buf;
+ rl_redisplay ();
+ return 0;
+}
+#else /* !HAVE_VARARGS_H */
+rl_message (format, arg1, arg2)
+ char *format;
+{
+ sprintf (msg_buf, format, arg1, arg2);
+ rl_display_prompt = msg_buf;
+ rl_redisplay ();
+ return 0;
+}
+#endif /* !HAVE_VARARGS_H */
+
+/* How to clear things from the "echo-area". */
+rl_clear_message ()
+{
+ rl_display_prompt = rl_prompt;
+ rl_redisplay ();
+ return 0;
+}
+
+rl_reset_line_state ()
+{
+ rl_on_new_line ();
+
+ rl_display_prompt = rl_prompt ? rl_prompt : "";
+ forced_display = 1;
+ return 0;
+}
+
+/* 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;
+
+ backspace (l);
+ for (i = 0; i < l; i++)
+ putc (' ', rl_outstream);
+ 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, */
+static void
+clear_to_eol (count)
+ int count;
+{
+#if !defined (__GO32__)
+ if (term_clreol)
+ {
+ tputs (term_clreol, 1, _rl_output_character_function);
+ }
+ else
+#endif /* !__GO32__ */
+ 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;
+}
+
+/* Insert COUNT characters from STRING to the output stream. */
+static void
+insert_some_chars (string, count)
+ char *string;
+ int count;
+{
+#if defined (__GO32__)
+ int row, col, width;
+ char *row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+
+ memcpy (row_start + col + count, row_start + col, width - col - count);
+
+ /* Place the text on the screen. */
+ _rl_output_some_chars (string, count);
+#else /* !_GO32 */
+
+ /* If IC is defined, then we do not have to "enter" insert mode. */
+ if (term_IC)
+ {
+ char *tgoto (), *buffer;
+ buffer = tgoto (term_IC, 0, count);
+ 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 (term_im && *term_im)
+ tputs (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 (term_ic && *term_ic)
+ {
+ for (i = count; i--; )
+ tputs (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 (term_ei && *term_ei)
+ tputs (term_ei, 1, _rl_output_character_function);
+ }
+#endif /* !__GO32__ */
+}
+
+/* Delete COUNT characters from the display line. */
+static void
+delete_chars (count)
+ int count;
+{
+#if defined (__GO32__)
+ int row, col, width;
+ char *row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+
+ memcpy (row_start + col, row_start + col + count, width - col - count);
+ memset (row_start + width - count, 0, count * 2);
+#else /* !_GO32 */
+
+ if (count > screenwidth) /* XXX */
+ return;
+
+ if (term_DC && *term_DC)
+ {
+ char *tgoto (), *buffer;
+ buffer = tgoto (term_DC, count, count);
+ tputs (buffer, count, _rl_output_character_function);
+ }
+ else
+ {
+ if (term_dc && *term_dc)
+ while (count--)
+ tputs (term_dc, 1, _rl_output_character_function);
+ }
+#endif /* !__GO32__ */
+}
+
+void
+_rl_update_final ()
+{
+ int full_lines;
+
+ full_lines = 0;
+ if (_rl_vis_botlin && visible_line[screenwidth * _rl_vis_botlin] == 0)
+ {
+ _rl_vis_botlin--;
+ full_lines = 1;
+ }
+ _rl_move_vert (_rl_vis_botlin);
+ if (full_lines && term_xn)
+ {
+ /* Remove final line-wrap flag in xterm. */
+ char *last_line;
+ last_line = &visible_line[screenwidth * _rl_vis_botlin];
+ _rl_move_cursor_relative (screenwidth - 1, last_line);
+ clear_to_eol (0);
+ putc (last_line[screenwidth - 1], rl_outstream);
+ }
+ _rl_vis_botlin = 0;
+ crlf ();
+ fflush (rl_outstream);
+ rl_display_fixed++;
+}
+
+/* Move to the start of the current line. */
+static void
+cr ()
+{
+ if (term_cr)
+ {
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_last_c_pos = 0;
+ }
+}
+
+/* Redisplay the current line after a SIGWINCH is received. */
+void
+_rl_redisplay_after_sigwinch ()
+{
+ char *t, *oldp;
+
+ /* 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 (term_cr)
+ {
+ tputs (term_cr, 1, _rl_output_character_function);
+ _rl_last_c_pos = 0;
+ if (term_clreol)
+ tputs (term_clreol, 1, _rl_output_character_function);
+ else
+ {
+ space_to_eol (screenwidth);
+ tputs (term_cr, 1, _rl_output_character_function);
+ }
+ if (_rl_last_v_pos > 0)
+ _rl_move_vert (0);
+ }
+ else
+ crlf ();
+
+ /* Redraw only the last line of a multi-line prompt. */
+ t = strrchr (rl_display_prompt, '\n');
+ if (t)
+ {
+ oldp = rl_display_prompt;
+ rl_display_prompt = ++t;
+ rl_forced_update_display ();
+ rl_display_prompt = oldp;
+ }
+ else
+ rl_forced_update_display ();
+}
diff --git a/gnu/lib/libreadline/doc/Makefile b/gnu/lib/libreadline/doc/Makefile
new file mode 100644
index 0000000..370458b
--- /dev/null
+++ b/gnu/lib/libreadline/doc/Makefile
@@ -0,0 +1,6 @@
+INFO = history readline
+
+history.info: hstech.texinfo hsuser.texinfo
+readline.info: rltech.texinfo rluser.texinfo
+
+.include <bsd.info.mk>
diff --git a/gnu/lib/libreadline/doc/history.texinfo b/gnu/lib/libreadline/doc/history.texinfo
new file mode 100644
index 0000000..cc80efa
--- /dev/null
+++ b/gnu/lib/libreadline/doc/history.texinfo
@@ -0,0 +1,113 @@
+\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
+
+@ignore
+last change: Wed Jul 20 09:57:17 EDT 1994
+@end ignore
+
+@set EDITION 2.0
+@set VERSION 2.0
+@set UPDATED 20 July 1994
+@set UPDATE-MONTH July 1994
+
+@ifinfo
+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, 1991 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
+
+@titlepage
+@sp 10
+@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 @*
+675 Massachusetts Avenue, @*
+Cambridge, MA 02139 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 Foundation.
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1989, 1991 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/gnu/lib/libreadline/doc/hstech.texinfo b/gnu/lib/libreadline/doc/hstech.texinfo
new file mode 100644
index 0000000..5f0f6004
--- /dev/null
+++ b/gnu/lib/libreadline/doc/hstech.texinfo
@@ -0,0 +1,489 @@
+@ignore
+This file documents the user interface to the GNU History library.
+
+Copyright (C) 1988, 1991 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 GNU History Library.
+It should be considered a technical guide.
+For information on the interactive use of 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 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.
+
+@node History Storage
+@section History Storage
+
+The history list is an array of history entries. A history entry is
+declared as follows:
+
+@example
+typedef struct _hist_entry @{
+ char *line;
+ char *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 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;
+@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
+present in GNU History.
+
+@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 ()
+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 ()
+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 (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, char *line, char *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 stifle_history (int max)
+Stifle the history list, remembering only the last @var{max} entries.
+@end deftypefun
+
+@deftypefun int unstifle_history ()
+Stop stifling the history. This returns the previous amount the
+history was stifled. The value is positive if the history was
+stifled, negative if it wasn't.
+@end deftypefun
+
+@deftypefun int history_is_stifled ()
+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 ()
+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 ()
+Returns the offset of the current history element.
+@end deftypefun
+
+@deftypefun {HIST_ENTRY *} current_history ()
+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}. 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 ()
+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 position in the history list to @var{pos}, an absolute index
+into the list.
+@end deftypefun
+
+@deftypefun {HIST_ENTRY *} previous_history ()
+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 ()
+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 (char *string, int direction)
+Search the history for @var{string}, starting at the current history
+offset. If @var{direction} < 0, then the search is through previous entries,
+else through subsequent. 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 (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} < 0, then the search is through previous
+entries, else through subsequent. 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 (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 (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 errno if not.
+@end deftypefun
+
+@deftypefun int read_history_range (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 (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}. Values
+returned are as in @code{read_history ()}.
+@end deftypefun
+
+@deftypefun int append_history (int nelements, char *filename)
+Append the last @var{nelements} of the history list to @var{filename}.
+@end deftypefun
+
+@deftypefun int history_truncate_file (char *filename, int nlines)
+Truncate the history file @var{filename}, leaving only the last
+@var{nlines} lines.
+@end deftypefun
+
+@node History Expansion
+@subsection History Expansion
+
+These functions implement @code{csh}-like 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 de-slashifying of 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 only 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 *} history_arg_extract (int first, int last, char *string)
+Extract a string segment consisting of the @var{first} through @var{last}
+arguments present in @var{string}. Arguments are broken up as in Bash.
+@end deftypefun
+
+@deftypefun {char *} get_history_event (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 (char *string)
+Return an array of tokens parsed out of @var{string}, much as the
+shell might. The tokens are split on white space and on the
+characters @code{()<>;&|$}, and shell quoting conventions are
+obeyed.
+@end deftypefun
+
+@node History Variables
+@section History Variables
+
+This section describes the externally visible variables exported by
+the 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 max_input_history
+The maximum number of history entries. This must be changed using
+@code{stifle_history ()}.
+@end deftypevar
+
+@deftypevar char history_expansion_char
+The character that starts a history event. The default is @samp{!}.
+@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_no_expand_chars
+The list of characters which inhibit history expansion if found immediately
+following @var{history_expansion_char}. The default is whitespace and
+@samp{=}.
+@end deftypevar
+
+@node History Programming Example
+@section History Programming Example
+
+The following program demonstrates simple use of the GNU History Library.
+
+@smallexample
+main ()
+@{
+ 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/gnu/lib/libreadline/doc/hsuser.texinfo b/gnu/lib/libreadline/doc/hsuser.texinfo
new file mode 100644
index 0000000..51327a3
--- /dev/null
+++ b/gnu/lib/libreadline/doc/hsuser.texinfo
@@ -0,0 +1,198 @@
+@ignore
+This file documents the user interface to the GNU History library.
+
+Copyright (C) 1988, 1991 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
+
+@ifset BashFeatures
+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 the GNU Readline Library Manual.
+@end ifset
+@ifclear BashFeatures
+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,
+@pxref{Programming with GNU History}.
+@end ifclear
+
+@menu
+* History Interaction:: What it feels like using History as a user.
+@end menu
+
+@node History Interaction
+@section History Interaction
+@cindex expansion
+
+The History library provides a history expansion feature that is similar
+to the history expansion provided by @code{csh}. The following text
+describes the syntax used to manipulate the history information.
+
+History expansion takes place in two parts. The first is to determine
+which line from the previous history 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 previous history is called the
+@dfn{event}, and the portions of that line that are acted upon are
+called @dfn{words}. The line is broken into words in the same fashion
+that Bash does, so that several English (or Unix) words
+surrounded by quotes are considered as one word.
+
+@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, @key{=} or @key{(}.
+
+@item @code{!!}
+Refer to the previous command. This is a synonym for @code{!-1}.
+
+@item @code{!n}
+Refer to command line @var{n}.
+
+@item @code{!-n}
+Refer to the command @var{n} lines back.
+
+@item @code{!string}
+Refer to the most recent command starting with @var{string}.
+
+@item @code{!?string}[@code{?}]
+Refer to the most recent command containing @var{string}.
+
+@item @code{!#}
+The entire command line typed so far.
+
+@item @code{^string1^string2^}
+Quick Substitution. Repeat the last command, replacing @var{string1}
+with @var{string2}. Equivalent to
+@code{!!:s/string1/string2/}.
+
+@end table
+
+@node Word Designators
+@subsection Word Designators
+
+A @key{:} separates the event specification from the word designator. It
+can be omitted if the word designator begins with a @key{^}, @key{$},
+@key{*} or @key{%}. Words are numbered from the beginning of the line,
+with the first word being denoted by a 0 (zero).
+
+@table @code
+
+@item 0 (zero)
+The @code{0}th word. For many applications, this is the command word.
+
+@item 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 @code{?string?} search.
+
+@item x-y
+A range of words; @code{-@var{y}} abbreviates @code{0-@var{y}}.
+
+@item *
+All of the words, except the @code{0}th. This is a synonym for @code{1-$}.
+It is not an error to use @key{*} if there is just one word in the event;
+the empty string is returned in that case.
+
+@item x*
+Abbreviates @code{x-$}
+
+@item x-
+Abbreviates @code{x-$} like @code{x*}, but omits the last word.
+
+@end table
+
+@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 @key{:}.
+
+@table @code
+
+@item h
+Remove a trailing pathname component, leaving only the head.
+
+@item r
+Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
+
+@item e
+Remove all but the trailing suffix.
+
+@item t
+Remove all leading pathname components, leaving the tail.
+
+@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 @code{q},
+but break into words at spaces, tabs, and newlines.
+@end ifset
+
+@item s/old/new/
+Substitute @var{new} for the first occurrence of @var{old} in the
+event line. Any delimiter may be used in place of @key{/}.
+The delimiter may be quoted in @var{old} and @var{new}
+with a single backslash. If @key{&} appears in @var{new},
+it is replaced by @var{old}. A single backslash will quote
+the @key{&}. 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 @code{s}, as in @code{gs/old/new/}, or with
+@code{&}.
+
+@end table
diff --git a/gnu/lib/libreadline/doc/readline.texinfo b/gnu/lib/libreadline/doc/readline.texinfo
new file mode 100644
index 0000000..ec14066
--- /dev/null
+++ b/gnu/lib/libreadline/doc/readline.texinfo
@@ -0,0 +1,111 @@
+\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
+
+@ignore
+last change: Thu Jul 21 16:02:40 EDT 1994
+@end ignore
+
+@set EDITION 2.0
+@set VERSION 2.0
+@set UPDATED 21 July 1994
+@set UPDATE-MONTH July 1994
+
+@ifinfo
+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, 1991 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
+
+@titlepage
+@sp 10
+@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 @*
+675 Massachusetts Avenue, @*
+Cambridge, MA 02139 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 Foundation.
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1989, 1991 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/gnu/lib/libreadline/doc/rltech.texinfo b/gnu/lib/libreadline/doc/rltech.texinfo
new file mode 100644
index 0000000..636c923
--- /dev/null
+++ b/gnu/lib/libreadline/doc/rltech.texinfo
@@ -0,0 +1,1406 @@
+@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, 1994 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 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 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 and then reads and returns
+a single line of text from the user. The line @code{readline}
+returns is allocated with @code{malloc ()}; you should @code{free ()}
+the line when you are done with it. The declaration for @code{readline}
+in ANSI C is
+
+@example
+@code{char *readline (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}, int (*@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.
+
+@menu
+* The Function Type:: C declarations to make code readable.
+* Function Writing:: Variables and calling conventions.
+@end menu
+
+@node The Function Type
+@subsection The Function Type
+
+For readabilty, we declare a new type of object, called
+@dfn{Function}. A @code{Function} is a C function which
+returns an @code{int}. The type declaration for @code{Function} is:
+
+@noindent
+@code{typedef int Function ();}
+
+The reason for declaring this new type is to make it easier to write
+code describing pointers to C functions. Let us say we had a variable
+called @var{func} which was a pointer to a function. Instead of the
+classic C declaration
+
+@code{int (*)()func;}
+
+@noindent
+we may write
+
+@code{Function *func;}
+
+@noindent
+Similarly, there are
+
+@example
+typedef void VFunction ();
+typedef char *CPFunction (); @r{and}
+typedef char **CPPFunction ();
+@end example
+
+@noindent
+for functions returning no value, @code{pointer to char}, and
+@code{pointer to pointer to char}, respectively.
+
+@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{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.
+
+@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}.
+@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 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_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 {char *} rl_prompt
+The prompt Readline uses. This is set from the argument to
+@code{readline ()}, and should not be assigned to directly.
+@end deftypevar
+
+@deftypevar {char *} rl_terminal_name
+The terminal type, used for initialization.
+@end deftypevar
+
+@deftypevar {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.
+@end deftypevar
+
+@deftypevar {FILE *} rl_outstream
+The stdio stream to which Readline performs output.
+@end deftypevar
+
+@deftypevar {Function *} 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 {Function *} rl_event_hook
+If non-zero, this is the address of a function to call periodically
+when readline is waiting for terminal input.
+@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}.
+* Utility Functions:: Generally useful functions and hooks.
+@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 (char *name, Function *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 ()
+Returns a new, empty keymap. The space for the keymap is allocated with
+@code{malloc ()}; you should @code{free ()} it when you are 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 ()
+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 ()
+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 (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
+
+@node Binding Keys
+@subsection Binding Keys
+
+You associate keys 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.
+
+These functions manage key bindings.
+
+@deftypefun int rl_bind_key (int key, Function *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, Function *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_generic_bind (int type, 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 (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.
+
+@deftypefun {Function *} rl_named_function (char *name)
+Return the function with name @var{name}.
+@end deftypefun
+
+@deftypefun {Function *} rl_function_of_keyseq (char *keyseq, Keymap map, int *type)
+Return the function invoked by @var{keyseq} in keymap @var{map}.
+If @var{map} is NULL, the current keymap is used. If @var{type} is
+not NULL, the type of the object is returned in it (one of @code{ISFUNC},
+@code{ISKMAP}, or @code{ISMACR}).
+@end deftypefun
+
+@deftypefun {char **} rl_invoking_keyseqs (Function *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 (Function *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 ()
+Print the names of all bindable Readline functions to @code{rl_outstream}.
+@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. I could use an undo function for
+the stock market.
+
+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:
+
+@example
+enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @};
+@end example
+
+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 undo 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 ()
+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 ()
+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 free_undo_list ()
+Free the existing undo list.
+@end deftypefun
+
+@deftypefun int rl_do_undo ()
+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 int rl_redisplay ()
+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 ()
+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 ()
+Tell the update routines that we have moved onto a new (empty) line,
+usually after ouputting a newline.
+@end deftypefun
+
+@deftypefun int rl_reset_line_state ()
+Reset the display state to a clean state and redisplay the current line
+starting on a new line.
+@end deftypefun
+
+@deftypefun int rl_message (va_alist)
+The arguments are a string as would be supplied to @code{printf}. 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 ()
+Clear the message in the echo area.
+@end deftypefun
+
+@node Modifying Text
+@subsection Modifying Text
+
+@deftypefun int rl_insert_text (char *text)
+Insert @var{text} into the line at the current cursor position.
+@end deftypefun
+
+@deftypefun int rl_delete_text (int start, int end)
+Delete the text between @var{start} and @var{end} in the current line.
+@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
+
+@node Utility Functions
+@subsection Utility Functions
+
+@deftypefun int rl_read_key ()
+Return the next character available. This handles input inserted into
+the input stream via @var{pending input} (@pxref{Readline Variables})
+and @code{rl_stuff_char ()}, macros, and characters read from 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 ()}.
+@end deftypefun
+
+@deftypefun int rl_initialize ()
+Initialize or re-initialize Readline's internal state.
+@end deftypefun
+
+@deftypefun int rl_reset_terminal (char *terminal_name)
+Reinitialize Readline's idea of the terminal settings using
+@var{terminal_name} as the terminal type (e.g., @code{vt100}).
+@end deftypefun
+
+@deftypefun int alphabetic (int c)
+Return 1 if @var{c} is an alphabetic character.
+@end deftypefun
+
+@deftypefun int numeric (int c)
+Return 1 if @var{c} is a numeric character.
+@end deftypefun
+
+@deftypefun int ding ()
+Ring the terminal bell, obeying the setting of @code{bell-style}.
+@end deftypefun
+
+The following are implemented as macros, defined in @code{chartypes.h}.
+
+@deftypefun int uppercase_p (int c)
+Return 1 if @var{c} is an uppercase alphabetic character.
+@end deftypefun
+
+@deftypefun int lowercase_p (int c)
+Return 1 if @var{c} is a lowercase alphabetic character.
+@end deftypefun
+
+@deftypefun int digit_p (int c)
+Return 1 if @var{c} is a numeric character.
+@end deftypefun
+
+@deftypefun int to_upper (int c)
+If @var{c} is a lowercase alphabetic character, return the corresponding
+uppercase character.
+@end deftypefun
+
+@deftypefun int to_lower (int c)
+If @var{c} is an uppercase alphabetic character, return the corresponding
+lowercase character.
+@end deftypefun
+
+@deftypefun int digit_value (int c)
+If @var{c} is a number, return the value it represents.
+@end deftypefun
+
+@subsection An 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 (uppercase_p (rl_line_buffer[i]))
+ rl_line_buffer[i] = to_lower (rl_line_buffer[i]);
+ else if (lowercase_p (rl_line_buffer[i]))
+ rl_line_buffer[i] = 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 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 Readline
+functions intended for interactive use: @var{count} and
+@var{invoking_key}. It isolates the word to be completed and calls
+@code{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{completion_matches ()} uses your
+@dfn{generator} function to generate the list of possible matches, and
+then returns the array of these matches. You should place the address
+of your generator function in @code{rl_completion_entry_function}.
+
+@item
+The generator function is called repeatedly from
+@code{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. When the generator function returns
+@code{(char *)NULL} this signals @code{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{completion_matches ()}). The default is to do filename completion.
+@end deftypefun
+
+@deftypevar {Function *} rl_completion_entry_function
+This is a pointer to the generator function for @code{completion_matches
+()}. If the value of @code{rl_completion_entry_function} is
+@code{(Function *)NULL} then the default filename generator function,
+@code{filename_entry_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{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 {char **} completion_matches (char *text, CPFunction *entry_func)
+Returns an array of @code{(char *)} which is a list of completions for
+@var{text}. If there are no completions, returns @code{(char **)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 *} filename_completion_function (char *text, int state)
+A generator function for filename completion in the general case. Note
+that completion in Bash is a little different because of all
+the pathnames that must be followed when looking up completions for a
+command. The Bash source is a useful reference for writing custom
+completion functions.
+@end deftypefun
+
+@deftypefun {char *} username_completion_function (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 {Function *} rl_completion_entry_function
+A pointer to the generator function for @code{completion_matches ()}.
+@code{NULL} means to use @code{filename_entry_function ()}, the default
+filename completer.
+@end deftypevar
+
+@deftypevar {CPPFunction *} 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} saying
+what the boundaries of @var{text} are. 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.
+@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 {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, i.e.,
+@code{" \t\n\"\\'`@@$><=;|&@{("}.
+@end deftypevar
+
+@deftypevar {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 {char *} rl_completer_quote_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
+@code{rl_completer_word_break_characters} are treated as any other character,
+unless they also appear within this list.
+@end deftypevar
+
+@deftypevar {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_ignore_completion_duplicates
+If non-zero, then disallow duplicates in the matches. 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 embedded word break
+characters.
+@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_completer_word_break_chars}. This is @emph{always} non-zero
+on entry, and can only be changed within a completion entry generator
+function.
+@end deftypevar
+
+@deftypevar {Function *} 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 {Function *} 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. It could be used
+to expand symbolic links or shell variables in pathnames.
+@end deftypevar
+
+@node A Short Completion Example
+@subsection A Short Completion Example
+
+Here is a small application demonstrating the use of the GNU Readline
+library. It is called @code{fileman}, and the source code resides in
+@file{examples/fileman.c}. This sample application provides
+completion of command names, line editing features, and access to the
+history list.
+
+@page
+@smallexample
+/* fileman.c -- A tiny application which demonstrates how to use the
+ GNU Readline library. This application interactively allows users
+ to manipulate files and their modes. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+
+#include <readline/readline.h>
+#include <readline/history.h>
+
+extern char *getwd ();
+extern char *xmalloc ();
+
+/* The names of functions that actually do the manipulation. */
+int com_list (), com_view (), com_rename (), com_stat (), com_pwd ();
+int com_delete (), com_help (), com_cd (), com_quit ();
+
+/* A structure which contains information on the commands this program
+ can understand. */
+
+typedef struct @{
+ char *name; /* User printable name of the function. */
+ Function *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, (Function *)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)
+ 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 ();
+char **fileman_completion ();
+
+/* 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 = (CPPFunction *)fileman_completion;
+@}
+
+/* Attempt to complete on the contents of TEXT. START and END show the
+ region of TEXT that contains the word to complete. We can use the
+ entire line 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)
+ 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 = 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)
+ 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 = getwd (dir);
+ 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);
+@}
+@end smallexample
diff --git a/gnu/lib/libreadline/doc/rluser.texinfo b/gnu/lib/libreadline/doc/rluser.texinfo
new file mode 100644
index 0000000..3567549
--- /dev/null
+++ b/gnu/lib/libreadline/doc/rluser.texinfo
@@ -0,0 +1,875 @@
+@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 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.
+
+@node Command Line Editing
+@chapter 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.
+@end menu
+
+@node Introduction and Notation
+@section Introduction to Line Editing
+
+The following paragraphs describe the notation used to represent
+keystrokes.
+
+The text @key{C-k} is read as `Control-K' and describes the character
+produced when the Control key is depressed and the @key{k} key is struck.
+
+The text @key{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 struck. If you do not have a meta key, the identical keystroke
+can be generated by typing @key{ESC} @i{first}, and then typing @key{k}.
+Either process is known as @dfn{metafying} the @key{k} key.
+
+The text @key{M-C-k} is read as `Meta-Control-k' and describes the
+character produced by @dfn{metafying} @key{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}, for more info).
+
+@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{RETURN}. You do not have to be at the
+end of the line to press @key{RETURN}; 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.
+@end menu
+
+@node Readline Bare Essentials
+@subsection 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 miss typing a character that you wanted to type, and
+not notice your error until you have typed several other characters. In
+that case, you can type @key{C-b} to move the cursor to the left, and then
+correct your mistake. Afterwards, you can move the cursor to the right
+with @key{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 basic bare
+essentials for editing the text of an input line follows.
+
+@table @asis
+@item @key{C-b}
+Move back one character.
+@item @key{C-f}
+Move forward one character.
+@item @key{DEL}
+Delete the character to the left of the cursor.
+@item @key{C-d}
+Delete the character underneath the cursor.
+@item @w{Printing characters}
+Insert the character into the line at the cursor.
+@item @key{C-_}
+Undo the last thing that you did. You can undo all the way back to an
+empty line.
+@end table
+
+@node Readline Movement Commands
+@subsection Readline Movement Commands
+
+
+The above table describes the most basic possible 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 @key{C-b}, @key{C-f},
+@key{C-d}, and @key{DEL}. Here are some commands for moving more rapidly
+about the line.
+
+@table @key
+@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.
+@item M-b
+Move backward a word.
+@item C-l
+Clear the screen, reprinting the current line at the top.
+@end table
+
+Notice how @key{C-f} moves forward a character, while @key{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.
+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 @key
+@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.
+
+@item M-DEL
+Kill from the cursor the start of the previous word, or if between
+words, to the start of the previous word.
+
+@item C-w
+Kill from the cursor to the previous whitespace. This is different than
+@key{M-DEL} because the word boundaries differ.
+
+@end table
+
+And, 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 @key
+@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 @key{C-y} or @key{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 @key{M--} @key{C-k}.
+
+The general way to pass numeric arguments to a command is to type meta
+digits before the command. If the first `digit' you type is a minus
+sign (@key{-}), 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 @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}.
+
+
+@node Readline Init File
+@section Readline Init File
+
+Although the Readline library comes with a set of Emacs-like
+keybindings installed by default,
+it is possible that you would like to use a different set
+of keybindings. You can customize programs that use Readline by putting
+commands in an @dfn{init} file in your home directory. The name of this
+@ifset BashFeatures
+file is taken from the value of the shell variable @code{INPUTRC}. If
+@end ifset
+@ifclear BashFeatures
+file is taken from the value of the environment variable @code{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 Syntax:: Syntax for the commands in the inputrc file.
+* Conditional Init Constructs:: Conditional key bindings in the inputrc file.
+@end menu
+
+@node Readline Init Syntax
+@subsection Readline Init Syntax
+
+There are only a few basic constructs allowed in the
+Readline init file. Blank lines are ignored.
+Lines beginning with a @key{#} are comments.
+Lines beginning with a @key{$} indicate conditional
+constructs (@pxref{Conditional Init Constructs}). Other lines
+denote variable settings and key bindings.
+
+@table @asis
+@item Variable Settings
+You can change the state of a few variables in Readline by
+using the @code{set} command within the init file. Here is how you
+would specify that you wish to use @code{vi} line editing commands:
+
+@example
+set editing-mode vi
+@end example
+
+Right now, there are only a few variables which can be set;
+so few, in fact, that we just list them here:
+
+@table @code
+
+@item editing-mode
+@vindex editing-mode
+The @code{editing-mode} variable controls which editing mode you are
+using. By default, Readline starts up in Emacs editing mode, where
+the keystrokes are most similar to Emacs. This variable can be
+set to either @code{emacs} or @code{vi}.
+
+@item horizontal-scroll-mode
+@vindex horizontal-scroll-mode
+This variable can be set to either @code{On} or @code{Off}. Setting it
+to @code{On} means that the text of the lines that you edit 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 @code{Off}.
+
+@item mark-modified-lines
+@vindex mark-modified-lines
+This variable, when set to @code{On}, says to display an asterisk
+(@samp{*}) at the start of history lines which have been modified.
+This variable is @code{off} by default.
+
+@item bell-style
+@vindex bell-style
+Controls what happens when Readline wants to ring the terminal bell.
+If set to @code{none}, Readline never rings the bell. If set to
+@code{visible}, Readline uses a visible bell if one is available.
+If set to @code{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{vi-comment} command is executed. The default value
+is @code{"#"}.
+
+@item meta-flag
+@vindex meta-flag
+If set to @code{on}, Readline will enable eight-bit input (it
+will not strip the eighth bit from the characters it reads),
+regardless of what the terminal claims it can support. The
+default value is @code{off}.
+
+@item convert-meta
+@vindex convert-meta
+If set to @code{on}, Readline will convert characters with the
+eigth bit set to an ASCII key sequence by stripping the eigth
+bit and prepending an @key{ESC} character, converting them to a
+meta-prefixed key sequence. The default value is @code{on}.
+
+@item output-meta
+@vindex output-meta
+If set to @code{on}, Readline will display characters with the
+eighth bit set directly rather than as a meta-prefixed escape
+sequence. The default is @code{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. The default limit is
+@code{100}.
+
+@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 show-all-if-ambiguous
+@vindex show-all-if-ambiguous
+This alters the default behavior of the completion functions. If
+set to @code{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 @code{off}.
+
+@item expand-tilde
+@vindex expand-tilde
+If set to @code{on}, tilde expansion is performed when Readline
+attempts word completion. The default is @code{off}.
+
+@end table
+
+@item Key Bindings
+The syntax for controlling key bindings in the init file is
+simple. First you have to know the name of the command that you
+want to change. The following pages contain tables of the command name,
+the default keybinding, and a short description of what the command
+does.
+
+Once you know the name of the command, simply place the name of the key
+you wish to bind the command to, a colon, and then the name of the
+command on a line in the init file. The name of the key
+can be expressed in different ways, depending on which is most
+comfortable for you.
+
+@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, @samp{C-u} is bound to the function
+@code{universal-argument}, and @samp{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).
+
+@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 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, @samp{C-u} is bound to the function
+@code{universal-argument} (just as it was in the first example),
+@samp{C-x C-r} is bound to the function @code{re-read-init-file}, and
+@samp{ESC [ 1 1 ~} is bound to insert the text @samp{Function Key 1}.
+The following 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{"}
+@item @kbd{\'}
+@key{'}
+@end table
+
+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. Backslash
+will quote any character in the macro text, including @key{"}
+and @key{'}.
+For example, the following binding will make @kbd{C-x \}
+insert a single @key{\} into the line:
+@example
+"\C-x\\": "\\"
+@end example
+
+@end table
+@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 three parser directives used.
+
+@ftable @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 the full name of the terminal and the
+portion of the terminal name before the first @samp{-}. This
+allows @var{sun} to match both @var{sun} and @var{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 it.
+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 you saw 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.
+@end ftable
+
+@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
+
+@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 this, or the 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, 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 @code{HISTCONTROL} variable. If this line was a 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, add it to the history list. If this line was a history
+line, then restore the history line to its original state.
+@end ifclear
+
+@item previous-history (C-p)
+Move `up' through the history list.
+
+@item next-history (C-n)
+Move `down' through the history list.
+
+@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 you are entering.
+
+@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 current 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 current 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). 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-., M-_)
+Insert last argument to the previous command (the last word on the
+previous line). With an
+argument, behave exactly like @code{yank-nth-arg}.
+
+@end ftable
+
+@node Commands For Text
+@subsection Commands For Changing Text
+
+@ftable @code
+@item delete-char (C-d)
+Delete the character under the cursor. If the cursor is at the
+beginning of the line, there are no characters in the line, and
+the last character typed was not C-d, then return EOF.
+
+@item backward-delete-char (Rubout)
+Delete the character behind the cursor. A numeric arg says to kill
+the characters instead of deleting them.
+
+@item quoted-insert (C-q, C-v)
+Add the next character that you type to the line verbatim. This is
+how to insert key sequences like @key{C-q}, for example.
+
+@item tab-insert (M-TAB)
+Insert a tab character.
+
+@item self-insert (a, b, A, 1, !, ...)
+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 argumentss don't work.
+
+@item transpose-words (M-t)
+Drag the word behind the cursor past the word in front of the cursor
+moving the cursor over that word as well.
+
+@item upcase-word (M-u)
+Uppercase the current (or following) word. With a negative argument,
+do the previous word, but do not move the cursor.
+
+@item downcase-word (M-l)
+Lowercase the current (or following) word. With a negative argument,
+do the previous word, but do not move the cursor.
+
+@item capitalize-word (M-c)
+Capitalize the current (or following) word. With a negative argument,
+do the previous word, but do not move the cursor.
+
+@end ftable
+
+@node Commands For Killing
+@subsection Killing And Yanking
+
+@ftable @code
+
+@item kill-line (C-k)
+Kill the text from the current cursor position 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.
+Save the killed text on the kill-ring.
+
+@item kill-whole-line ()
+Kill all characters on the current line, no matter where the
+cursor is. By default, this is unbound.
+
+@item kill-word (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 @code{forward-word}.
+
+@item backward-kill-word (M-DEL)
+Kill the word behind the cursor. Word boundaries are the same
+as @code{backward-word}.
+
+@item unix-word-rubout (C-w)
+Kill the word behind the cursor, 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 yank (C-y)
+Yank the top of the kill ring into the buffer at the current
+cursor position.
+
+@item 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.
+@end ftable
+
+@node Numeric Arguments
+@subsection Specifying Numeric Arguments
+@ftable @code
+
+@item 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.
+
+@item universal-argument ()
+Each time this is executed, the argument count is multiplied by four.
+The argument count is initially one, so executing this function the
+first time makes the argument count four. 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 (TAB)
+Attempt to do completion on the text before the cursor. This is
+application-specific. Generally, if you are typing a filename
+argument, you can do filename completion; if you are typing a command,
+you can do command completion, if you are typing in a symbol to GDB, you
+can do symbol name completion, if you are typing in a variable to Bash,
+you can do variable name completion, and so on.
+@ifset BashFeatures
+See the Bash manual page for a complete list of available completion
+functions.
+@end ifset
+
+@item possible-completions (M-?)
+List the possible completions of the text before the cursor.
+
+@item insert-completions ()
+Insert all completions of the text before point that would have
+been generated by @code{possible-completions}. By default, this
+is not bound to a key.
+
+@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 your init 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, ...)
+Run the command that is bound to the corresoponding uppercase
+character.
+
+@item prefix-meta (ESC)
+Make the next character that you type be metafied. This is for people
+without a meta key. Typing @samp{ESC f} is equivalent to typing
+@samp{M-f}.
+
+@item undo (C-_, 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 typing the @code{undo}
+command enough times to get back to the beginning.
+
+@item tilde-expand (M-~)
+Perform tilde expansion on the current word.
+
+@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.
+
+@ifset BashFeatures
+@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 the way the shell does when it reads it. This
+performs alias and history expansion as well as all of the shell
+word expansions.
+
+@item history-expand-line (M-^)
+Perform history expansion on the current line.
+
+@item insert-last-argument (M-., 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 emacs-editing-mode (C-e)
+When in @code{vi} editing mode, this causes a switch back to
+emacs editing mode, as if the command @code{set -o emacs} had
+been executed.
+
+@end ifset
+
+@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 Posix 1003.2 standard.
+
+@ifset BashFeatures
+In order to switch interactively between @code{Emacs} and @code{Vi}
+editing modes, use the @code{set -o emacs} and @code{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 M-C-j (toggle-editing-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 following lines with @samp{j}, and
+so forth.
diff --git a/gnu/lib/libreadline/emacs_keymap.c b/gnu/lib/libreadline/emacs_keymap.c
new file mode 100644
index 0000000..849d85f
--- /dev/null
+++ b/gnu/lib/libreadline/emacs_keymap.c
@@ -0,0 +1,885 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#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, (Function *)0x0 }, /* Control-@ */
+ { ISFUNC, rl_beg_of_line }, /* Control-a */
+ { ISFUNC, rl_backward }, /* Control-b */
+ { ISFUNC, (Function *)0x0 }, /* Control-c */
+ { ISFUNC, rl_delete }, /* Control-d */
+ { ISFUNC, rl_end_of_line }, /* Control-e */
+ { ISFUNC, rl_forward }, /* 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, (Function *)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, (Function *)emacs_ctlx_keymap }, /* Control-x */
+ { ISFUNC, rl_yank }, /* Control-y */
+ { ISFUNC, (Function *)0x0 }, /* Control-z */
+ { ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
+ { ISFUNC, (Function *)0x0 }, /* Control-\ */
+ { ISFUNC, (Function *)0x0 }, /* Control-] */
+ { ISFUNC, (Function *)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 }, /* ( */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* ) */
+#else
+ { ISFUNC, rl_insert }, /* ) */
+#endif /* !PAREN_MATCHING */
+ { 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 }, /* \ */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* ] */
+#else
+ { ISFUNC, rl_insert }, /* ] */
+#endif /* !PAREN_MATCHING */
+ { 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 }, /* | */
+#if defined (PAREN_MATCHING)
+ { ISFUNC, rl_insert_close }, /* } */
+#else
+ { ISFUNC, rl_insert }, /* } */
+#endif /* !PAREN_MATCHING */
+ { 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, (Function *)0x0 }, /* Meta-Control-@ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-a */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-b */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-c */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-d */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-e */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* Meta-Control-k */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-l */
+ { ISFUNC, rl_vi_editing_mode }, /* Meta-Control-m */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-n */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-o */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-p */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-q */
+ { ISFUNC, rl_revert_line }, /* Meta-Control-r */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-s */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-t */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-u */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-v */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-w */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-x */
+ { ISFUNC, rl_yank_nth_arg }, /* Meta-Control-y */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-z */
+
+ { ISFUNC, rl_complete }, /* Meta-Control-[ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-\ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-] */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-^ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, (Function *)0x0 }, /* Meta-SPACE */
+ { ISFUNC, (Function *)0x0 }, /* Meta-! */
+ { ISFUNC, (Function *)0x0 }, /* Meta-" */
+ { ISFUNC, (Function *)0x0 }, /* Meta-# */
+ { ISFUNC, (Function *)0x0 }, /* Meta-$ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-% */
+ { ISFUNC, rl_tilde_expand }, /* Meta-& */
+ { ISFUNC, (Function *)0x0 }, /* Meta-' */
+ { ISFUNC, (Function *)0x0 }, /* Meta-( */
+ { ISFUNC, (Function *)0x0 }, /* Meta-) */
+ { ISFUNC, (Function *)0x0 }, /* Meta-* */
+ { ISFUNC, (Function *)0x0 }, /* Meta-+ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-, */
+ { ISFUNC, rl_digit_argument }, /* Meta-- */
+ { ISFUNC, rl_yank_last_arg}, /* Meta-. */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* Meta-: */
+ { ISFUNC, (Function *)0x0 }, /* Meta-; */
+ { ISFUNC, rl_beginning_of_history }, /* Meta-< */
+ { ISFUNC, (Function *)0x0 }, /* Meta-= */
+ { ISFUNC, rl_end_of_history }, /* Meta-> */
+ { ISFUNC, rl_possible_completions }, /* Meta-? */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */
+ { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-] */
+ { ISFUNC, (Function *)0x0 }, /* Meta-^ */
+ { ISFUNC, rl_yank_last_arg }, /* Meta-_ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (Function *)0x0 }, /* Meta-a */
+ { ISFUNC, rl_backward_word }, /* Meta-b */
+ { ISFUNC, rl_capitalize_word }, /* Meta-c */
+ { ISFUNC, rl_kill_word }, /* Meta-d */
+ { ISFUNC, (Function *)0x0 }, /* Meta-e */
+ { ISFUNC, rl_forward_word }, /* Meta-f */
+ { ISFUNC, (Function *)0x0 }, /* Meta-g */
+ { ISFUNC, (Function *)0x0 }, /* Meta-h */
+ { ISFUNC, (Function *)0x0 }, /* Meta-i */
+ { ISFUNC, (Function *)0x0 }, /* Meta-j */
+ { ISFUNC, (Function *)0x0 }, /* Meta-k */
+ { ISFUNC, rl_downcase_word }, /* Meta-l */
+ { ISFUNC, (Function *)0x0 }, /* Meta-m */
+ { ISFUNC, rl_noninc_forward_search }, /* Meta-n */
+ { ISFUNC, (Function *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */
+ { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */
+ { ISFUNC, (Function *)0x0 }, /* Meta-q */
+ { ISFUNC, rl_revert_line }, /* Meta-r */
+ { ISFUNC, (Function *)0x0 }, /* Meta-s */
+ { ISFUNC, rl_transpose_words }, /* Meta-t */
+ { ISFUNC, rl_upcase_word }, /* Meta-u */
+ { ISFUNC, (Function *)0x0 }, /* Meta-v */
+ { ISFUNC, (Function *)0x0 }, /* Meta-w */
+ { ISFUNC, (Function *)0x0 }, /* Meta-x */
+ { ISFUNC, rl_yank_pop }, /* Meta-y */
+ { ISFUNC, (Function *)0x0 }, /* Meta-z */
+
+ /* Final punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* Meta-{ */
+ { ISFUNC, (Function *)0x0 }, /* Meta-| */
+ { ISFUNC, (Function *)0x0 }, /* Meta-} */
+ { ISFUNC, rl_tilde_expand }, /* Meta-~ */
+ { ISFUNC, rl_backward_kill_word }, /* Meta-rubout */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
+
+ /* Control keys. */
+ { ISFUNC, (Function *)0x0 }, /* Control-@ */
+ { ISFUNC, (Function *)0x0 }, /* Control-a */
+ { ISFUNC, (Function *)0x0 }, /* Control-b */
+ { ISFUNC, (Function *)0x0 }, /* Control-c */
+ { ISFUNC, (Function *)0x0 }, /* Control-d */
+ { ISFUNC, (Function *)0x0 }, /* Control-e */
+ { ISFUNC, (Function *)0x0 }, /* Control-f */
+ { ISFUNC, rl_abort }, /* Control-g */
+ { ISFUNC, (Function *)0x0 }, /* Control-h */
+ { ISFUNC, (Function *)0x0 }, /* Control-i */
+ { ISFUNC, (Function *)0x0 }, /* Control-j */
+ { ISFUNC, (Function *)0x0 }, /* Control-k */
+ { ISFUNC, (Function *)0x0 }, /* Control-l */
+ { ISFUNC, (Function *)0x0 }, /* Control-m */
+ { ISFUNC, (Function *)0x0 }, /* Control-n */
+ { ISFUNC, (Function *)0x0 }, /* Control-o */
+ { ISFUNC, (Function *)0x0 }, /* Control-p */
+ { ISFUNC, (Function *)0x0 }, /* Control-q */
+ { ISFUNC, rl_re_read_init_file }, /* Control-r */
+ { ISFUNC, (Function *)0x0 }, /* Control-s */
+ { ISFUNC, (Function *)0x0 }, /* Control-t */
+ { ISFUNC, rl_undo_command }, /* Control-u */
+ { ISFUNC, (Function *)0x0 }, /* Control-v */
+ { ISFUNC, (Function *)0x0 }, /* Control-w */
+ { ISFUNC, (Function *)0x0 }, /* Control-x */
+ { ISFUNC, (Function *)0x0 }, /* Control-y */
+ { ISFUNC, (Function *)0x0 }, /* Control-z */
+ { ISFUNC, (Function *)0x0 }, /* Control-[ */
+ { ISFUNC, (Function *)0x0 }, /* Control-\ */
+ { ISFUNC, (Function *)0x0 }, /* Control-] */
+ { ISFUNC, (Function *)0x0 }, /* Control-^ */
+ { ISFUNC, (Function *)0x0 }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, (Function *)0x0 }, /* SPACE */
+ { ISFUNC, (Function *)0x0 }, /* ! */
+ { ISFUNC, (Function *)0x0 }, /* " */
+ { ISFUNC, (Function *)0x0 }, /* # */
+ { ISFUNC, (Function *)0x0 }, /* $ */
+ { ISFUNC, (Function *)0x0 }, /* % */
+ { ISFUNC, (Function *)0x0 }, /* & */
+ { ISFUNC, (Function *)0x0 }, /* ' */
+ { ISFUNC, rl_start_kbd_macro }, /* ( */
+ { ISFUNC, rl_end_kbd_macro }, /* ) */
+ { ISFUNC, (Function *)0x0 }, /* * */
+ { ISFUNC, (Function *)0x0 }, /* + */
+ { ISFUNC, (Function *)0x0 }, /* , */
+ { ISFUNC, (Function *)0x0 }, /* - */
+ { ISFUNC, (Function *)0x0 }, /* . */
+ { ISFUNC, (Function *)0x0 }, /* / */
+
+ /* Regular digits. */
+ { ISFUNC, (Function *)0x0 }, /* 0 */
+ { ISFUNC, (Function *)0x0 }, /* 1 */
+ { ISFUNC, (Function *)0x0 }, /* 2 */
+ { ISFUNC, (Function *)0x0 }, /* 3 */
+ { ISFUNC, (Function *)0x0 }, /* 4 */
+ { ISFUNC, (Function *)0x0 }, /* 5 */
+ { ISFUNC, (Function *)0x0 }, /* 6 */
+ { ISFUNC, (Function *)0x0 }, /* 7 */
+ { ISFUNC, (Function *)0x0 }, /* 8 */
+ { ISFUNC, (Function *)0x0 }, /* 9 */
+
+ /* A little more punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* : */
+ { ISFUNC, (Function *)0x0 }, /* ; */
+ { ISFUNC, (Function *)0x0 }, /* < */
+ { ISFUNC, (Function *)0x0 }, /* = */
+ { ISFUNC, (Function *)0x0 }, /* > */
+ { ISFUNC, (Function *)0x0 }, /* ? */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* [ */
+ { ISFUNC, (Function *)0x0 }, /* \ */
+ { ISFUNC, (Function *)0x0 }, /* ] */
+ { ISFUNC, (Function *)0x0 }, /* ^ */
+ { ISFUNC, (Function *)0x0 }, /* _ */
+ { ISFUNC, (Function *)0x0 }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (Function *)0x0 }, /* a */
+ { ISFUNC, (Function *)0x0 }, /* b */
+ { ISFUNC, (Function *)0x0 }, /* c */
+ { ISFUNC, (Function *)0x0 }, /* d */
+ { ISFUNC, rl_call_last_kbd_macro }, /* e */
+ { ISFUNC, (Function *)0x0 }, /* f */
+ { ISFUNC, (Function *)0x0 }, /* g */
+ { ISFUNC, (Function *)0x0 }, /* h */
+ { ISFUNC, (Function *)0x0 }, /* i */
+ { ISFUNC, (Function *)0x0 }, /* j */
+ { ISFUNC, (Function *)0x0 }, /* k */
+ { ISFUNC, (Function *)0x0 }, /* l */
+ { ISFUNC, (Function *)0x0 }, /* m */
+ { ISFUNC, (Function *)0x0 }, /* n */
+ { ISFUNC, (Function *)0x0 }, /* o */
+ { ISFUNC, (Function *)0x0 }, /* p */
+ { ISFUNC, (Function *)0x0 }, /* q */
+ { ISFUNC, (Function *)0x0 }, /* r */
+ { ISFUNC, (Function *)0x0 }, /* s */
+ { ISFUNC, (Function *)0x0 }, /* t */
+ { ISFUNC, (Function *)0x0 }, /* u */
+ { ISFUNC, (Function *)0x0 }, /* v */
+ { ISFUNC, (Function *)0x0 }, /* w */
+ { ISFUNC, (Function *)0x0 }, /* x */
+ { ISFUNC, (Function *)0x0 }, /* y */
+ { ISFUNC, (Function *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* { */
+ { ISFUNC, (Function *)0x0 }, /* | */
+ { ISFUNC, (Function *)0x0 }, /* } */
+ { ISFUNC, (Function *)0x0 }, /* ~ */
+ { ISFUNC, rl_backward_kill_line }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
diff --git a/gnu/lib/libreadline/examples/Inputrc b/gnu/lib/libreadline/examples/Inputrc
new file mode 100644
index 0000000..5b71bd7
--- /dev/null
+++ b/gnu/lib/libreadline/examples/Inputrc
@@ -0,0 +1,65 @@
+# 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.
+#
+
+# 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/gnu/lib/libreadline/examples/Makefile b/gnu/lib/libreadline/examples/Makefile
new file mode 100644
index 0000000..3f9659e
--- /dev/null
+++ b/gnu/lib/libreadline/examples/Makefile
@@ -0,0 +1,12 @@
+# This is the Makefile for the examples subdirectory of readline. -*- text -*-
+#
+
+EXECUTABLES = fileman
+CFLAGS = -g -I..
+LDFLAGS = -g -L..
+
+fileman: fileman.o
+ $(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap
+
+fileman.o: fileman.c
+
diff --git a/gnu/lib/libreadline/examples/fileman.c b/gnu/lib/libreadline/examples/fileman.c
new file mode 100644
index 0000000..3ecb9f1
--- /dev/null
+++ b/gnu/lib/libreadline/examples/fileman.c
@@ -0,0 +1,425 @@
+/* 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 *getwd ();
+extern char *xmalloc ();
+
+/* The names of functions that actually do the manipulation. */
+int com_list (), com_view (), com_rename (), com_stat (), com_pwd ();
+int com_delete (), com_help (), com_cd (), com_quit ();
+
+/* A structure which contains information on the commands this program
+ can understand. */
+
+typedef struct {
+ char *name; /* User printable name of the function. */
+ Function *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, (Function *)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)
+ 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 ();
+char **fileman_completion ();
+
+/* 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 = (CPPFunction *)fileman_completion;
+}
+
+/* Attempt to complete on the contents of TEXT. START and END show the
+ region of TEXT that contains the word to complete. We can use the
+ entire line 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)
+ 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 = 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)
+ 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 = getwd (dir);
+ 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/gnu/lib/libreadline/examples/histexamp.c b/gnu/lib/libreadline/examples/histexamp.c
new file mode 100644
index 0000000..eceb66d
--- /dev/null
+++ b/gnu/lib/libreadline/examples/histexamp.c
@@ -0,0 +1,82 @@
+main ()
+{
+ 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/gnu/lib/libreadline/examples/manexamp.c b/gnu/lib/libreadline/examples/manexamp.c
new file mode 100644
index 0000000..3496efa
--- /dev/null
+++ b/gnu/lib/libreadline/examples/manexamp.c
@@ -0,0 +1,94 @@
+/* manexamp.c -- The examples which appear in the documentation are here. */
+
+#include <stdio.h>
+#include <readline/readline.h>
+
+
+/* **************************************************************** */
+/* */
+* 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 (uppercase_p (rl_line_buffer[start]))
+ rl_line_buffer[start] = to_lower (rl_line_buffer[start]);
+ else if (lowercase_p (rl_line_buffer[start]))
+ rl_line_buffer[start] = to_upper (rl_line_buffer[start]);
+ }
+
+ /* Move point to on top of the last character changed. */
+ rl_point = end - direction;
+}
+
diff --git a/gnu/lib/libreadline/funmap.c b/gnu/lib/libreadline/funmap.c
new file mode 100644
index 0000000..9255974
--- /dev/null
+++ b/gnu/lib/libreadline/funmap.c
@@ -0,0 +1,299 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#endif /* BUFSIZ */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "rlconf.h"
+#include "readline.h"
+
+static int qsort_string_compare ();
+
+FUNMAP **funmap = (FUNMAP **)NULL;
+static int funmap_size = 0;
+static int funmap_entry = 0;
+
+/* 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-char", rl_backward },
+ { "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 },
+ { "clear-screen", rl_clear_screen },
+ { "complete", rl_complete },
+ { "delete-char", rl_delete },
+ { "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 },
+ { "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 },
+ { "forward-char", rl_forward },
+ { "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-completions", rl_insert_completions },
+ { "kill-whole-line", rl_kill_full_line },
+ { "kill-line", rl_kill_line },
+ { "kill-word", rl_kill_word },
+ { "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 },
+ { "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 },
+ { "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-bWord", rl_vi_bWord },
+ { "vi-bracktype", rl_vi_bracktype },
+ { "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-comment", rl_vi_comment },
+ { "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-first-print", rl_vi_first_print },
+ { "vi-fword", rl_vi_fword },
+ { "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-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, (Function *)NULL }
+};
+
+rl_add_funmap_entry (name, function)
+ char *name;
+ Function *function;
+{
+ if (funmap_entry + 2 >= funmap_size)
+ if (!funmap)
+ funmap = (FUNMAP **)xmalloc ((funmap_size = 80) * sizeof (FUNMAP *));
+ else
+ funmap =
+ (FUNMAP **)xrealloc (funmap, (funmap_size += 80) * 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 = 0;
+
+/* 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. */
+char **
+rl_funmap_names ()
+{
+ char **result = (char **)NULL;
+ int result_size, result_index;
+
+ result_size = result_index = 0;
+
+ /* Make sure that the function map has been initialized. */
+ rl_initialize_funmap ();
+
+ for (result_index = 0; funmap[result_index]; result_index++)
+ {
+ if (result_index + 2 > result_size)
+ {
+ if (!result)
+ result = (char **)xmalloc ((result_size = 20) * sizeof (char *));
+ else
+ result = (char **)
+ xrealloc (result, (result_size += 20) * sizeof (char *));
+ }
+
+ result[result_index] = funmap[result_index]->name;
+ result[result_index + 1] = (char *)NULL;
+ }
+
+ qsort (result, result_index, sizeof (char *), qsort_string_compare);
+ return (result);
+}
+
+/* Stupid comparison routine for qsort () ing strings. */
+static int
+qsort_string_compare (s1, s2)
+ register char **s1, **s2;
+{
+ int r;
+
+ r = **s1 - **s2;
+ if (r == 0)
+ r = strcmp (*s1, *s2);
+ return r;
+}
+
+/* Things that mean `Control'. */
+char *possible_control_prefixes[] = {
+ "Control-", "C-", "CTRL-", (char *)NULL
+};
+
+char *possible_meta_prefixes[] = {
+ "Meta", "M-", (char *)NULL
+};
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "history: Out of virtual memory!\n");
+ abort ();
+}
+#endif /* STATIC_MALLOC */
diff --git a/gnu/lib/libreadline/history.c b/gnu/lib/libreadline/history.c
new file mode 100644
index 0000000..94c0ad5
--- /dev/null
+++ b/gnu/lib/libreadline/history.c
@@ -0,0 +1,2218 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, 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
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+#include <errno.h>
+
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include "memalloc.h"
+#include "history.h"
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
+#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
+
+#ifndef savestring
+# ifndef strcpy
+extern char *strcpy ();
+# endif
+#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
+#endif
+
+#ifndef whitespace
+#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
+#endif
+
+#ifndef digit_p
+#define digit_p(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#ifndef digit_value
+#define 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
+
+/* 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
+
+static char error_pointer;
+
+static char *subst_lhs;
+static char *subst_rhs;
+static int subst_lhs_len = 0;
+static int subst_rhs_len = 0;
+
+static char *get_history_word_specifier ();
+static char *history_find_word ();
+
+#if defined (SHELL)
+extern char *single_quote ();
+#endif
+
+/* **************************************************************** */
+/* */
+/* 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 = 0;
+
+/* If HISTORY_STIFLED is non-zero, then this is the maximum number of
+ entries to remember. */
+int max_input_history;
+
+/* The current location of the interactive history pointer. Just makes
+ life easier for outside callers. */
+static int history_offset = 0;
+
+/* The number of strings currently stored in the input_history list. */
+int history_length = 0;
+
+/* The current number of slots allocated to the input_history. */
+static int history_size = 0;
+
+/* The number of slots to increase the_history by. */
+#define DEFAULT_HISTORY_GROW_SIZE 50
+
+/* 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=";
+
+/* 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;
+
+ result = 0;
+
+ for (i = 0; the_history && the_history[i]; i++)
+ result += strlen (the_history[i]->line);
+
+ return (result);
+}
+
+/* Place STRING at the end of the history list. The data field
+ is set to NULL. */
+void
+add_history (string)
+ char *string;
+{
+ HIST_ENTRY *temp;
+
+ if (history_stifled && (history_length == max_input_history))
+ {
+ register int i;
+
+ /* If the history is stifled, and history_length is zero,
+ and it equals max_input_history, 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)
+ {
+ 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;
+ char *line;
+ char *data;
+{
+ HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+ HIST_ENTRY *old_value;
+
+ if (which >= history_length)
+ return ((HIST_ENTRY *)NULL);
+
+ old_value = the_history[which];
+
+ temp->line = savestring (line);
+ temp->data = data;
+ the_history[which] = temp;
+
+ return (old_value);
+}
+
+/* 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);
+}
+
+/* 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. */
+
+#define ANCHORED_SEARCH 1
+#define NON_ANCHORED_SEARCH 0
+
+static int
+history_search_internal (string, direction, anchored)
+ char *string;
+ int direction, anchored;
+{
+ register int i, reverse;
+ register char *line;
+ register int line_index;
+ int string_len;
+
+ 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)
+
+ 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 = 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)
+ 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)
+ char *string;
+ int direction;
+{
+ return (history_search_internal (string, direction, ANCHORED_SEARCH));
+}
+
+/* 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;
+
+ if (which >= history_length || !history_length)
+ return_value = (HIST_ENTRY *)NULL;
+ else
+ {
+ register int i;
+ 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;
+{
+ if (max < 0)
+ max = 0;
+
+ if (history_length > max)
+ {
+ register int i, j;
+
+ /* This loses because we cannot free the data. */
+ for (i = 0; i < (history_length - max); 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 = max;
+}
+
+/* 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. */
+int
+unstifle_history ()
+{
+ int result = max_input_history;
+
+ if (history_stifled)
+ {
+ result = -result;
+ history_stifled = 0;
+ }
+
+ return (result);
+}
+
+int
+history_is_stifled ()
+{
+ return (history_stifled);
+}
+
+/* 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)
+ char *filename;
+{
+ char *return_val = filename ? savestring (filename) : (char *)NULL;
+
+ if (!return_val)
+ {
+ char *home;
+ int home_len;
+
+ home = getenv ("HOME");
+
+ if (!home)
+ home = ".";
+
+ home_len = strlen (home);
+ /* strlen(".history") == 8 */
+ return_val = xmalloc (2 + home_len + 8);
+
+ strcpy (return_val, home);
+ return_val[home_len] = '/';
+ strcpy (return_val + home_len + 1, ".history");
+ }
+
+ 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)
+ 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)
+ char *filename;
+ int from, to;
+{
+ register int line_start, line_end;
+ char *input, *buffer = (char *)NULL;
+ int file, current_line;
+ struct stat finfo;
+
+ input = history_filename (filename);
+ file = open (input, O_RDONLY, 0666);
+
+ if ((file < 0) || (fstat (file, &finfo) == -1))
+ goto error_and_exit;
+
+ buffer = xmalloc ((int)finfo.st_size + 1);
+
+ if (read (file, buffer, finfo.st_size) != finfo.st_size)
+ {
+ error_and_exit:
+ if (file >= 0)
+ close (file);
+
+ if (input)
+ free (input);
+
+ if (buffer)
+ free (buffer);
+
+ return (errno);
+ }
+
+ close (file);
+
+ /* Set TO to larger than end of file if negative. */
+ if (to < 0)
+ to = finfo.st_size;
+
+ /* Start at beginning of file, work to end. */
+ line_start = line_end = current_line = 0;
+
+ /* Skip lines until we are at FROM. */
+ while (line_start < finfo.st_size && current_line < from)
+ {
+ for (line_end = line_start; line_end < finfo.st_size; line_end++)
+ if (buffer[line_end] == '\n')
+ {
+ current_line++;
+ line_start = line_end + 1;
+ if (current_line == from)
+ break;
+ }
+ }
+
+ /* If there are lines left to gobble, then gobble them now. */
+ for (line_end = line_start; line_end < finfo.st_size; line_end++)
+ if (buffer[line_end] == '\n')
+ {
+ buffer[line_end] = '\0';
+
+ if (buffer[line_start])
+ add_history (buffer + line_start);
+
+ current_line++;
+
+ if (current_line >= to)
+ break;
+
+ line_start = line_end + 1;
+ }
+
+ if (input)
+ free (input);
+
+ if (buffer)
+ free (buffer);
+
+ return (0);
+}
+
+/* Truncate the history file FNAME, leaving only LINES trailing lines.
+ If FNAME is NULL, then use ~/.history. */
+int
+history_truncate_file (fname, lines)
+ char *fname;
+ register int lines;
+{
+ register int i;
+ int file, chars_read;
+ char *buffer = (char *)NULL, *filename;
+ struct stat finfo;
+
+ filename = history_filename (fname);
+ file = open (filename, O_RDONLY, 0666);
+
+ if (file == -1 || fstat (file, &finfo) == -1)
+ goto truncate_exit;
+
+ buffer = xmalloc ((int)finfo.st_size + 1);
+ chars_read = read (file, buffer, finfo.st_size);
+ close (file);
+
+ if (chars_read <= 0)
+ goto truncate_exit;
+
+ /* Count backwards from the end of buffer until we have passed
+ LINES lines. */
+ for (i = chars_read - 1; lines && i; i--)
+ {
+ if (buffer[i] == '\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 ( ; i; i--)
+ if (buffer[i] == '\n')
+ {
+ i++;
+ break;
+ }
+
+ /* Write only if there are more lines in the file than we want to
+ truncate to. */
+ if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1))
+ {
+ write (file, buffer + i, finfo.st_size - i);
+ close (file);
+ }
+
+ truncate_exit:
+ if (buffer)
+ free (buffer);
+
+ free (filename);
+ return 0;
+}
+
+#define HISTORY_APPEND 0
+#define HISTORY_OVERWRITE 1
+
+/* 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)
+ char *filename;
+ int nelements, overwrite;
+{
+ register int i;
+ char *output = history_filename (filename);
+ int file, mode;
+
+ mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND;
+
+ if ((file = open (output, mode, 0666)) == -1)
+ {
+ if (output)
+ free (output);
+
+ return (errno);
+ }
+
+ 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). */
+ {
+ register int j = 0;
+ int buffer_size = 0;
+ char *buffer;
+
+ /* Calculate the total number of bytes to write. */
+ for (i = history_length - nelements; i < history_length; i++)
+ buffer_size += 1 + strlen (the_history[i]->line);
+
+ /* Allocate the buffer, and fill it. */
+ buffer = xmalloc (buffer_size);
+
+ for (i = history_length - nelements; i < history_length; i++)
+ {
+ strcpy (buffer + j, the_history[i]->line);
+ j += strlen (the_history[i]->line);
+ buffer[j++] = '\n';
+ }
+
+ write (file, buffer, buffer_size);
+ free (buffer);
+ }
+
+ close (file);
+
+ if (output)
+ free (output);
+
+ return (0);
+}
+
+/* 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;
+ 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)
+ char *filename;
+{
+ return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
+}
+
+/* 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 ()
+{
+ if ((history_offset == history_length) || !the_history)
+ return ((HIST_ENTRY *)NULL);
+ else
+ return (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 ()
+{
+ if (!history_offset)
+ return ((HIST_ENTRY *)NULL);
+ else
+ return (the_history[--history_offset]);
+}
+
+/* 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 ()
+{
+ if (history_offset == history_length)
+ return ((HIST_ENTRY *)NULL);
+ else
+ return (the_history[++history_offset]);
+}
+
+/* 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 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 = offset - history_base;
+
+ if (local_index >= history_length ||
+ local_index < 0 ||
+ !the_history)
+ return ((HIST_ENTRY *)NULL);
+ return (the_history[local_index]);
+}
+
+/* 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)
+ char *string;
+ int dir, pos;
+{
+ int ret, 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;
+}
+
+/* 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);
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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 in a !?string? search. */
+static char *search_string = (char *)NULL;
+
+/* The last string matched by a !?string? search. */
+static char *search_match = (char *)NULL;
+
+/* 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)
+ char *string;
+ int *caller_index;
+ int delimiting_quote;
+{
+ register int i = *caller_index;
+ register char c;
+ HIST_ENTRY *entry;
+ int which, sign = 1;
+ int local_index, search_mode, substring_okay = 0;
+ 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. */
+
+ if (string[i] != history_expansion_char)
+ return ((char *)NULL);
+
+ /* Move on to the specification. */
+ i++;
+
+#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 (digit_p (string[i]))
+ {
+ /* Get the extent of the digits and compute the value. */
+ for (which = 0; digit_p (string[i]); i++)
+ which = (which * 10) + 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 ((!substring_okay && (whitespace (c) || c == ':' ||
+#if defined (SHELL)
+ member (c, ";&()|<>") ||
+#endif /* SHELL */
+ string[i] == delimiting_quote)) ||
+ string[i] == '\n' ||
+ (substring_okay && string[i] == '?'))
+ break;
+
+ temp = xmalloc (1 + (i - local_index));
+ strncpy (temp, &string[local_index], (i - local_index));
+ temp[i - local_index] = '\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)
+
+ search_mode = substring_okay ? NON_ANCHORED_SEARCH : ANCHORED_SEARCH;
+ while (1)
+ {
+ local_index = history_search_internal (temp, -1, search_mode);
+
+ 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)
+ {
+ if (search_string)
+ free (search_string);
+ search_string = temp;
+
+ if (search_match)
+ 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
+}
+#if defined (SHELL)
+/* 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
+rl_string_extract_single_quoted (string, sindex)
+ char *string;
+ int *sindex;
+{
+ register int i = *sindex;
+
+ while (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 = 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;
+}
+#endif /* SHELL */
+
+static char *
+hist_error(s, start, current, errtype)
+ char *s;
+ int start, current, errtype;
+{
+ char *temp, *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;
+ default:
+ emsg = "unknown expansion error";
+ elen = 23;
+ break;
+ }
+
+ temp = 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 = (char *) NULL;
+
+ i = *iptr;
+
+ for (si = i; str[si] && str[si] != delimiter; si++)
+ if (str[si] == '\\' && str[si + 1] == delimiter)
+ si++;
+
+ if (si > i || is_rhs)
+ {
+ s = 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 = 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 = 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 = 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;
+
+ result = 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 (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
+ quoted_search_delimiter = string[i - 1];
+ event = get_history_event (string, &i, quoted_search_delimiter);
+ }
+
+ if (!event)
+ {
+ *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. */
+ if (!word_spec)
+ temp = savestring (event);
+ else
+ {
+ temp = savestring (word_spec);
+ 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;
+
+#if defined (SHELL)
+ case 'q':
+ want_quotes = 'q';
+ break;
+
+ case 'x':
+ want_quotes = 'x';
+ break;
+#endif /* SHELL */
+
+ /* :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, *t;
+ int delimiter, failed, si, l_temp;
+
+ if (c == 's')
+ {
+ if (i + 2 < (int)strlen (string))
+ 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)
+ {
+ if (subst_lhs)
+ 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;
+ }
+ }
+
+ /* If there is no lhs, the substitution can't succeed. */
+ if (subst_lhs_len == 0)
+ {
+ *ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
+ free (result);
+ free (temp);
+ return -1;
+ }
+
+ if (subst_rhs)
+ 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;
+
+ 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 = 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 defined (SHELL)
+ if (want_quotes)
+ {
+ char *x;
+
+ if (want_quotes == 'q')
+ x = single_quote (temp);
+ else if (want_quotes == 'x')
+ x = quote_breaks (temp);
+ else
+ x = savestring (temp);
+
+ free (temp);
+ temp = x;
+ }
+#endif /* SHELL */
+
+ n = strlen (temp);
+ if (n > result_len)
+ result = 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 = xrealloc (result, result_len); \
+ } \
+ strcpy (result + j - sl, s); \
+ } \
+ while (0)
+
+#define ADD_CHAR(c) \
+ do \
+ { \
+ if (j >= result_len - 1) \
+ result = 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;
+
+ /* Used when adding the string. */
+ char *temp;
+
+ /* 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 = xmalloc (result_len = 256);
+ result[0] = '\0';
+
+ only_printing = modified = 0;
+ l = strlen (hstring);
+
+ /* Grovel the string. Only backslash 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 = xmalloc (l + 5);
+
+ string[0] = string[1] = history_expansion_char;
+ string[2] = ':';
+ string[3] = 's';
+ strcpy (string + 4, hstring);
+ l += 4;
+ }
+ else
+ {
+ 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++)
+ {
+ cc = string[i + 1];
+ if (string[i] == history_expansion_char)
+ {
+ if (!cc || member (cc, history_no_expand_chars))
+ continue;
+#if defined (SHELL)
+ /* The shell uses ! as a pattern negation character
+ in globbing [...] expressions, so let those pass
+ without expansion. */
+ else if (i > 0 && (string[i - 1] == '[') &&
+ member (']', string + i + 1))
+ continue;
+#endif /* SHELL */
+ else
+ break;
+ }
+#if defined (SHELL)
+ else if (string[i] == '\'')
+ {
+ /* If this is bash, single quotes inhibit history expansion. */
+ i++;
+ rl_string_extract_single_quoted (string, &i);
+ }
+ else if (string[i] == '\\')
+ {
+ /* If this is bash, allow backslashes to quote single
+ quotes and
+ the history expansion character. */
+ if (cc == '\'' || cc == history_expansion_char)
+ i++;
+ }
+#endif /* SHELL */
+ }
+
+ 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 (tchar == history_expansion_char)
+ tchar = -3;
+
+ switch (tchar)
+ {
+ default:
+ ADD_CHAR (string[i]);
+ break;
+
+ case '\\':
+ passc++;
+ ADD_CHAR (tchar);
+ break;
+
+#if defined (SHELL)
+ case '\'':
+ {
+ /* If this is bash, single quotes inhibit history expansion. */
+ int quote, slen;
+
+ quote = i++;
+ rl_string_extract_single_quoted (string, &i);
+
+ slen = i - quote + 2;
+ temp = xmalloc (slen);
+ strncpy (temp, string + quote, slen);
+ temp[slen - 1] = '\0';
+ ADD_STRING (temp);
+ free (temp);
+ break;
+ }
+#endif /* SHELL */
+
+ 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 = 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 (digit_p (spec[i]) && expecting_word_spec)
+ {
+ for (first = 0; digit_p (spec[i]); i++)
+ first = (first * 10) + 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 (digit_p (spec[i]))
+ {
+ for (last = 0; digit_p (spec[i]); i++)
+ last = (last * 10) + digit_value (spec[i]);
+ }
+ else if (spec[i] == '$')
+ {
+ i++;
+ last = '$';
+ }
+ else if (!spec[i] || spec[i] == ':') /* could be modifier separator */
+ 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;
+ char *string;
+{
+ register int i, len;
+ char *result = (char *)NULL;
+ int size = 0, offset = 0;
+ 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 = xmalloc (size + 1);
+ result[0] = '\0';
+
+ for (i = first; 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)
+ char *string;
+ int wind, *indp;
+{
+ char **result = (char **)NULL;
+ register int i, start, result_index, size;
+ int len;
+
+ i = result_index = size = 0;
+
+ /* Get a token, and stuff it into RESULT. The tokens are split
+ exactly where the shell would split them. */
+ while (string[i])
+ {
+ int delimiter = 0;
+
+ /* Skip leading whitespace. */
+ for (; string[i] && whitespace (string[i]); i++)
+ ;
+ if (!string[i] || 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], "\"'`"))
+ 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], " \t\n;&()|<>")))
+ break;
+
+ if (!delimiter && member (string[i], "\"'`"))
+ 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 >= 0 && 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] = 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)
+ 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)
+ 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;
+}
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)xmalloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+
+ return (temp);
+}
+
+static void
+memory_error_and_abort ()
+{
+ fprintf (stderr, "history: Out of virtual memory!\n");
+ abort ();
+}
+#endif /* STATIC_MALLOC */
+
+/* **************************************************************** */
+/* */
+/* Test Code */
+/* */
+/* **************************************************************** */
+#ifdef TEST
+main ()
+{
+ char line[1024], *t;
+ int done = 0;
+
+ line[0] = 0;
+
+ while (!done)
+ {
+ fprintf (stdout, "history%% ");
+ t = fgets (line, 1024, stdin);
+
+ if (!t)
+ strcpy (line, "quit");
+
+ if (line[0])
+ {
+ char *expansion;
+ int result;
+
+ using_history ();
+
+ result = history_expand (line, &expansion);
+ strcpy (line, expansion);
+ free (expansion);
+ if (result)
+ fprintf (stderr, "%s\n", line);
+
+ if (result < 0)
+ continue;
+
+ add_history (line);
+ }
+
+ if (strcmp (line, "quit") == 0) done = 1;
+ if (strcmp (line, "save") == 0) write_history (0);
+ if (strcmp (line, "read") == 0) read_history (0);
+ if (strcmp (line, "list") == 0)
+ {
+ register HIST_ENTRY **the_list = history_list ();
+ register int i;
+
+ if (the_list)
+ for (i = 0; the_list[i]; i++)
+ fprintf (stdout, "%d: %s\n", i + history_base, the_list[i]->line);
+ }
+ if (strncmp (line, "delete", strlen ("delete")) == 0)
+ {
+ int which;
+ if ((sscanf (line + strlen ("delete"), "%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");
+ }
+ }
+ }
+}
+
+#endif /* TEST */
+
+/*
+* Local variables:
+* compile-command: "gcc -g -DTEST -o history history.c"
+* end:
+*/
diff --git a/gnu/lib/libreadline/history.h b/gnu/lib/libreadline/history.h
new file mode 100644
index 0000000..6935efd
--- /dev/null
+++ b/gnu/lib/libreadline/history.h
@@ -0,0 +1,181 @@
+/* History.h -- the names of functions that you can call in history. */
+
+/* The structure used to store a history entry. */
+typedef struct _hist_entry {
+ char *line;
+ char *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 ();
+
+/* Return the current HISTORY_STATE of the history. */
+extern HISTORY_STATE *history_get_history_state ();
+
+/* Set the state of the current history array to STATE. */
+extern void history_set_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 ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* Stifle the history list, remembering only MAX number of entries. */
+extern void stifle_history ();
+
+/* 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 ();
+
+/* Return 1 if the history is stifled, 0 if it is not. */
+extern int history_is_stifled ();
+
+/* 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 ();
+
+/* Returns the number which says what history element we are now
+ looking at. */
+extern int where_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 the history entry which is logically at OFFSET in the history
+ array. OFFSET is relative to history_base. */
+extern HIST_ENTRY *history_get ();
+
+/* 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 ();
+
+/* Moving around the history list. */
+
+/* Set the position in the history list to POS. */
+int history_set_pos ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* Search the history for STRING, starting at history_offset.
+ The search is anchored: matching lines must begin with string. */
+extern int history_search_prefix ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* Truncate the history file, leaving only the last NLINES lines. */
+extern int history_truncate_file ();
+
+/* 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 ();
+
+/* 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 ();
+
+/* Return the text of the history event beginning at the current
+ offset into STRING. */
+extern char *get_history_event ();
+
+/* Return an array of tokens, much as the shell might. The tokens are
+ parsed out of STRING. */
+extern char **history_tokenize ();
+
+/* Exported history variables. */
+extern int history_base;
+extern int history_length;
+extern int max_input_history;
+extern char history_expansion_char;
+extern char history_subst_char;
+extern char history_comment_char;
+extern char *history_no_expand_chars;
diff --git a/gnu/lib/libreadline/isearch.c b/gnu/lib/libreadline/isearch.c
new file mode 100644
index 0000000..1a0193f
--- /dev/null
+++ b/gnu/lib/libreadline/isearch.c
@@ -0,0 +1,378 @@
+/* **************************************************************** */
+/* */
+/* I-Search and Searching */
+/* */
+/* **************************************************************** */
+
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "memalloc.h"
+#include "readline.h"
+#include "history.h"
+
+#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
+#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
+
+/* Variables imported from other files in the readline library. */
+extern Keymap _rl_keymap;
+extern HIST_ENTRY *saved_line_for_history;
+extern int rl_line_buffer_len;
+extern int rl_point, rl_end;
+extern char *rl_line_buffer;
+
+extern char *xmalloc (), *xrealloc ();
+
+static int rl_search_history ();
+
+/* 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;
+
+/* Search backwards through the history looking for a string which is typed
+ interactively. Start with the current line. */
+rl_reverse_search_history (sign, key)
+ int sign;
+ int 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. */
+rl_forward_search_history (sign, key)
+ int sign;
+ int 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;
+
+ message = xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30);
+ *message = '\0';
+
+#if defined (NOTDEF)
+ if (where != -1)
+ sprintf (message, "[%d]", where + history_base);
+#endif /* NOTDEF */
+
+ strcat (message, "(");
+
+ if (reverse_p)
+ strcat (message, "reverse-");
+
+ strcat (message, "i-search)`");
+
+ if (search_string)
+ strcat (message, search_string);
+
+ strcat (message, "': ");
+ rl_message ("%s", message, 0);
+ free (message);
+ rl_redisplay ();
+}
+
+/* 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;
+ int 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 = (char *)NULL;
+
+ /* The length of LINES. */
+ int hlen;
+
+ /* Where we get LINES from. */
+ HIST_ENTRY **hlist = history_list ();
+
+ register int i = 0;
+ int orig_point = rl_point;
+ int orig_line = where_history ();
+ int last_found_line = orig_line;
+ int c, done = 0, found, failed, sline_len;
+
+ /* 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 = (direction < 0);
+
+ /* Create an arrary of pointers to the lines that we want to search. */
+ maybe_replace_line ();
+ 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 (saved_line_for_history)
+ lines[i] = saved_line_for_history->line;
+ else
+ {
+ /* Keep track of this so we can free it. */
+ allocated_line = 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;
+
+ /* Initialize search parameters. */
+ search_string = 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;
+ while (!done)
+ {
+ Function *f = (Function *)NULL;
+
+ /* Read a key and decide how to proceed. */
+ c = rl_read_key ();
+
+ /* Hack C to Do What I Mean. */
+ if (_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;
+ }
+
+ switch (c)
+ {
+ case ESC:
+ done = 1;
+ continue;
+
+ case -1:
+ if (!search_string_index)
+ continue;
+ else
+ {
+ if (reverse)
+ --line_index;
+ else
+ {
+ if (line_index != sline_len)
+ ++line_index;
+ else
+ ding ();
+ }
+ }
+ break;
+
+ /* switch directions */
+ case -2:
+ direction = -direction;
+ reverse = (direction < 0);
+ break;
+
+ case CTRL ('G'):
+ strcpy (rl_line_buffer, lines[orig_line]);
+ rl_point = orig_point;
+ rl_end = strlen (rl_line_buffer);
+ rl_clear_message ();
+ free (allocated_line);
+ free (lines);
+ return 0;
+
+ default:
+ if (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT)
+ {
+ rl_execute_next (c);
+ done = 1;
+ continue;
+ }
+ else
+ {
+ /* Add character to search string and continue search. */
+ if (search_string_index + 2 >= search_string_size)
+ {
+ search_string_size += 128;
+ search_string = xrealloc (search_string, search_string_size);
+ }
+ search_string[search_string_index++] = c;
+ search_string[search_string_index] = '\0';
+ break;
+ }
+ }
+
+ found = failed = 0;
+ while (1)
+ {
+ 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... */
+ if (reverse)
+ line_index = sline_len - search_string_index;
+ else
+ line_index = 0;
+ }
+
+ if (failed)
+ {
+ /* We cannot find the search string. Ding the bell. */
+ 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)
+ {
+ int line_len;
+
+ prev_line_found = lines[i];
+ line_len = strlen (lines[i]);
+
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+
+ strcpy (rl_line_buffer, lines[i]);
+ rl_point = line_index;
+ rl_end = line_len;
+ 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]);
+
+ /* Free the search string. */
+ free (search_string);
+
+ if (last_found_line < orig_line)
+ rl_get_previous_history (orig_line - last_found_line);
+ else
+ rl_get_next_history (last_found_line - orig_line);
+
+ /* If the string was not found, put point at the end of the line. */
+ if (line_index < 0)
+ line_index = strlen (rl_line_buffer);
+ rl_point = line_index;
+ rl_clear_message ();
+
+ free (allocated_line);
+ free (lines);
+
+ return 0;
+}
diff --git a/gnu/lib/libreadline/keymaps.c b/gnu/lib/libreadline/keymaps.c
new file mode 100644
index 0000000..e1be552
--- /dev/null
+++ b/gnu/lib/libreadline/keymaps.c
@@ -0,0 +1,200 @@
+/* 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "rlconf.h"
+#include "keymaps.h"
+#include "emacs_keymap.c"
+
+#if defined (VI_MODE)
+#include "vi_keymap.c"
+#endif
+
+extern int rl_do_lowercase_version ();
+extern int rl_rubout (), rl_insert ();
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* **************************************************************** */
+/* */
+/* 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 = (Function *)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;
+ 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;
+ }
+ }
+}
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)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 ();
+}
+#endif /* STATIC_MALLOC */
diff --git a/gnu/lib/libreadline/keymaps.h b/gnu/lib/libreadline/keymaps.h
new file mode 100644
index 0000000..f0eda3d
--- /dev/null
+++ b/gnu/lib/libreadline/keymaps.h
@@ -0,0 +1,95 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _KEYMAPS_H_
+#define _KEYMAPS_H_
+
+#if defined (READLINE_LIBRARY)
+# include "chardefs.h"
+#else
+# include <readline/chardefs.h>
+#endif
+
+#if !defined (__FUNCTION_DEF)
+# define __FUNCTION_DEF
+typedef int Function ();
+typedef void VFunction ();
+typedef char *CPFunction ();
+typedef char **CPPFunction ();
+#endif
+
+/* A keymap contains one entry for each key in the ASCII set.
+ Each entry consists of a type and a pointer.
+ POINTER is the address of a function to run, or the
+ address of a keymap to indirect through.
+ TYPE says which kind of thing POINTER is. */
+typedef struct _keymap_entry {
+ char type;
+ Function *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). */
+#define KEYMAP_SIZE 256
+
+/* I wanted to make the above structure contain a union of:
+ union { Function *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 ();
+
+/* Return a new keymap which is a copy of MAP. */
+extern Keymap rl_copy_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 ();
+
+extern void rl_discard_keymap ();
+
+/* 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 ();
+
+/* Return the current keymap. */
+extern Keymap rl_get_keymap ();
+
+/* Set the current keymap to MAP. */
+extern void rl_set_keymap ();
+
+#endif /* _KEYMAPS_H_ */
diff --git a/gnu/lib/libreadline/memalloc.h b/gnu/lib/libreadline/memalloc.h
new file mode 100644
index 0000000..750d53d
--- /dev/null
+++ b/gnu/lib/libreadline/memalloc.h
@@ -0,0 +1,56 @@
+/* memalloc.h -- consolidate code for including alloca.h or malloc.h and
+ defining alloca. */
+
+/* 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (__MEMALLOC_H__)
+# define __MEMALLOC_H__
+
+#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H)
+# define HAVE_ALLOCA_H
+#endif
+
+#if defined (__GNUC__) && !defined (HAVE_ALLOCA)
+# define HAVE_ALLOCA
+#endif
+
+#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA)
+# define HAVE_ALLOCA
+#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */
+
+#if !defined (BUILDING_MAKEFILE)
+
+#if defined (__GNUC__)
+# undef alloca
+# define alloca __builtin_alloca
+#else /* !__GNUC__ */
+# if defined (HAVE_ALLOCA_H)
+# if defined (IBMESA)
+# include <malloc.h>
+# else /* !IBMESA */
+# include <alloca.h>
+# endif /* !IBMESA */
+# else
+extern char *alloca ();
+# endif /* !HAVE_ALLOCA_H */
+#endif /* !__GNUC__ */
+
+#endif /* !BUILDING_MAKEFILE */
+
+#endif /* __MEMALLOC_H__ */
diff --git a/gnu/lib/libreadline/parens.c b/gnu/lib/libreadline/parens.c
new file mode 100644
index 0000000..57a9777
--- /dev/null
+++ b/gnu/lib/libreadline/parens.c
@@ -0,0 +1,130 @@
+/* parens.c -- Implemenation of matching parenthesis 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include "rlconf.h"
+
+#if !defined (PAREN_MATCHING)
+
+rl_insert_close (count, invoking_key)
+ int count, invoking_key;
+{
+ return (rl_insert (count, invoking_key));
+}
+
+#else /* PAREN_MATCHING */
+
+#include <stdio.h>
+#include <sys/types.h>
+#if defined (FD_SET)
+# include <sys/time.h>
+#endif /* FD_SET */
+#include "readline.h"
+
+extern int rl_explicit_arg;
+
+/* Non-zero means try to blink the matching open parenthesis when the
+ close parenthesis is inserted. */
+#if defined (FD_SET)
+int rl_blink_matching_paren = 1;
+#else /* !FD_SET */
+int rl_blink_matching_paren = 0;
+#endif /* !FD_SET */
+
+static int find_matching_open ();
+
+rl_insert_close (count, invoking_key)
+ int count, invoking_key;
+{
+ if (rl_explicit_arg || !rl_blink_matching_paren)
+ rl_insert (count, invoking_key);
+ else
+ {
+#if defined (FD_SET)
+ int orig_point, match_point, ready;
+ struct timeval timer;
+ fd_set readfds;
+
+ rl_insert (1, invoking_key);
+ rl_redisplay ();
+ 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 = 1;
+ timer.tv_usec = 500;
+
+ orig_point = rl_point;
+ rl_point = match_point;
+ rl_redisplay ();
+ ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
+ rl_point = orig_point;
+#else /* !FD_SET */
+ rl_insert (count, invoking_key);
+#endif /* !FD_SET */
+ }
+ 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 ((string[i] == '\'') || (string[i] == '"'))
+ delimiter = rl_line_buffer[i];
+ else if (!delimiter && (string[i] == closer))
+ level++;
+ else if (!delimiter && (string[i] == opener))
+ level--;
+
+ if (!level)
+ break;
+ }
+ return (i);
+}
+
+#endif /* PAREN_MATCHING */
diff --git a/gnu/lib/libreadline/posixstat.h b/gnu/lib/libreadline/posixstat.h
new file mode 100644
index 0000000..7d1cece
--- /dev/null
+++ b/gnu/lib/libreadline/posixstat.h
@@ -0,0 +1,149 @@
+/* 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This file should be included instead of <sys/stat.h>.
+ It relies on the local sys/stat.h to work though. */
+#if !defined (_POSIXSTAT_H)
+#define _POSIXSTAT_H
+
+#include <sys/stat.h>
+
+#if defined (isc386)
+# if !defined (S_IFDIR)
+# define S_IFDIR 0040000
+# endif /* !S_IFDIR */
+# if !defined (S_IFMT)
+# define S_IFMT 0170000
+# endif /* !S_IFMT */
+#endif /* isc386 */
+
+/* This text is taken directly from the Cadmus I was trying to
+ compile on:
+ the following MACROs are defined for X/OPEN compatibility
+ however, is the param correct ??
+ #define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK)
+
+ Well, the answer is no. Thus... */
+#if defined (BrainDeath)
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISFIFO
+# undef S_ISREG
+#endif /* BrainDeath */
+
+/* Posix 1003.1 5.6.1.1 <sys/stat.h> 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 <sys/stat.h> 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/gnu/lib/libreadline/readline.3 b/gnu/lib/libreadline/readline.3
new file mode 100644
index 0000000..7f8c2c3
--- /dev/null
+++ b/gnu/lib/libreadline/readline.3
@@ -0,0 +1,1216 @@
+.\"
+.\" MAN PAGE COMMENTS to
+.\"
+.\" Chet Ramey
+.\" Information Network Services
+.\" Case Western Reserve University
+.\" chet@ins.CWRU.Edu
+.\"
+.\" Last Change: Wed Jul 20 16:13:11 EDT 1994
+.\"
+.TH READLINE 3 "1994 July 26" GNU
+.\"
+.\" 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 <readline/readline.h>
+#include <readline/history.h>
+.ft
+.fi
+.LP
+.nf
+.ft B
+typedef int Function ();
+.LP
+.nf
+.ft B
+char *readline (prompt)
+char *prompt;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_add_defun (name, function, key)
+char *name;
+Function *function;
+int key;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_bind_key (key, function)
+int key;
+Function *function;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_unbind_key (key)
+int key;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_bind_key_in_map (key, function, keymap)
+int key;
+Function *function;
+Keymap keymap;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_unbind_key_in_map (key, keymap)
+int key;
+Keymap keymap;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_macro_bind (keyseq, macro, keymap)
+char *keyseq, *macro;
+Keymap keymap;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_variable_bind (variable, value)
+char *variable, *value;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_parse_and_bind (line)
+char *line;
+.ft
+.fi
+.LP
+.nf
+.ft B
+int rl_translate_keyseq (keyseq, array, len)
+char *keyseq, *array;
+int *len;
+.ft
+.fi
+.LP
+.nf
+.ft B
+Function *rl_named_function (command)
+char *command;
+.ft
+.fi
+.LP
+.nf
+.ft B
+Function *rl_function_of_keyseq (keyseq, keymap, type)
+char *keyseq;
+Keymap keymap;
+int *type;
+.ft
+.fi
+.LP
+.nf
+.ft B
+char **rl_invoking_keyseqs (function)
+Function *function;
+.ft
+.fi
+.LP
+.nf
+.ft B
+char **rl_invoking_keyseqs_in_map (function, keymap)
+Function *function;
+Keymap keymap;
+.ft
+.fi
+.LP
+.nf
+.ft B
+void rl_function_dumper (readable)
+int readable;
+.ft
+.fi
+.LP
+.nf
+.ft B
+char **rl_funmap_names ()
+.ft
+.fi
+.SH COPYRIGHT
+.if n Readline is Copyright (C) 1989, 1991 by the Free Software Foundation, Inc.
+.if t Readline is Copyright \(co 1989, 1991 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 null, no prompt is issued. The line returned is allocated with
+.IR malloc (3),
+so 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
+In the following descriptions,
+.B keymap
+can be one of \fIemacs_keymap, emacs_meta_keymap, emacs_ctlx_keymap,
+vi_insertion_keymap, or vi_movement_keymap\fP.
+.LP
+.B rl_add_defun
+makes
+.B name
+appear as a bindable readline command, and makes
+.B function
+be the function called when that command is invoked. If
+.B key
+is not \-1, it is bound to
+.B function
+in the current keymap.
+.LP
+.B rl_bind_key
+causes
+.B key
+to invoke
+.BR function .
+The binding is made in the current keymap.
+.LP
+.B rl_unbind_key
+removes the binding for
+.B key
+in the current keymap.
+.LP
+.B rl_bind_key_in_map
+makes the
+.B key
+entry in
+.B keymap
+invoke
+.BR function .
+.LP
+.B rl_unbind_key_in_map
+removes the binding for
+.B key
+in keymap
+.BR keymap .
+.LP
+.B rl_macro_bind
+makes
+.B keyseq
+insert the string
+.BR macro .
+The binding is performed in
+.BR keymap .
+.LP
+.B rl_variable_bind
+sets the value of the readline variable
+.B variable
+to
+.BR value .
+.LP
+.B rl_parse_and_bind
+takes as an argument a line of the same form as the readline startup
+file (see
+.SM
+.B INITIALIZATION FILE
+below) and executes the commands therein.
+.LP
+.B rl_translate_keyseq
+converts
+.B keyseq
+into a new string, storing the result in
+.BR array .
+This translates control and meta prefixes and the readline
+character escape sequences (see
+.SM
+.B Key Bindings
+below). The length of the translated sequence is returned in
+.BR *len .
+.LP
+.B rl_named_function
+returns the function that is executed when the readline
+command
+.B command
+is invoked.
+.LP
+.B rl_function_of_keyseq
+returns the function that is executed when
+.B keyseq
+is read and
+.B keymap
+is the current keymap.
+.B type
+is set to indicate whether the return value corresponds to a
+function, macro, or auxiliary keymap.
+.LP
+.B rl_invoking_keyseqs
+returns all of the key sequences in the current keymap that
+invoke
+.BR function .
+.LP
+.B rl_invoking_keyseqs_in_map
+returns all of the key sequences in
+.B keymap
+that invoke
+.BR function .
+.LP
+.B rl_function_dumper
+prints all of the readline functions and their bindings to the
+readline output stream. If
+.B readable
+is non\-zero, the output is formattted so that it can be read
+back in to restore the bindings.
+.LP
+.B rl_funmap_names
+returns an array of all known readline bindable function names.
+The array is sorted.
+.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.
+.LP
+Unless otherwise stated,
+the other functions return 0 on success and non\-zero on failure.
+.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 name of this file is taken from the value of the
+.B INPUTRC
+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
+into the
+.FN ~/.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 RUBOUT ,
+.IR DEL ,
+.IR ESC ,
+.IR LFD ,
+.IR NEWLINE ,
+.IR RET ,
+.IR RETURN ,
+.IR SPC ,
+.IR SPACE ,
+and
+.IR TAB .
+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.
+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
+.I >&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.
+.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
+.BR "Function Key 1" .
+The full set of escape sequences is
+.RS
+.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 "
+.TP
+.B \e'
+literal '
+.RE
+.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. Backslash
+will quote any 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
+.BR Off .
+The variables and their default values are:
+.PP
+.PD 0
+.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 editing\-mode (emacs)
+Controls whether readline begins with a set of key bindings similar
+to \fIemacs\fP or \fIvi\fP.
+.B editing\-mode
+can be set to either
+.B emacs
+or
+.BR vi .
+.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 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 vi\-comment
+command is executed.
+.TP
+.B meta\-flag (Off)
+If set to \fBOn\fP, readline will enable eight-bit input (that is,
+it will not strip the high bit from the characters it reads),
+regardless of what the terminal claims it can support.
+.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 prepending an
+escape character (in effect, using escape as the \fImeta prefix\fP).
+.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 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 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 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 expand\-tilde (Off)
+If set to \fBon\fP, tilde expansion is performed when readline
+attempts word completion.
+.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 three 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:
+.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 you saw 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.
+.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.
+.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 this, or the 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. By default, this is unbound.
+.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, add it to the history list. If the line is a modified
+history line, then restore the history line 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 point. This
+is a non-incremental search. By default, this command is unbound.
+.TP
+.B history\-search\-backward
+Search backward through the history for the string of characters
+between the start of the current line and the current point. This
+is a non-incremental search. By default, this command is unbound.
+.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 (the current
+cursor position). 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 on
+the previous line). With an argument,
+behave exactly like \fByank-nth-arg\fP.
+.PD
+.SS Commands for Changing Text
+.PP
+.PD 0
+.TP
+.B delete\-char (C\-d)
+Delete the character under the cursor. If point is at the
+beginning of the line, there are no characters in the line, and
+the last character typed was not
+.BR C\-d ,
+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 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.
+Point moves forward as well. If point is at the end of the line, then
+transpose the two characters before point. Negative arguments don't work.
+.TP
+.B transpose\-words (M\-t)
+Drag the word behind the cursor past the word in front of the cursor
+moving the cursor over that word as well.
+.TP
+.B upcase\-word (M\-u)
+Uppercase the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
+.TP
+.B downcase\-word (M\-l)
+Lowercase the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
+.TP
+.B capitalize\-word (M\-c)
+Capitalize the current (or following) word. With a negative argument,
+do the previous word, but do not move point.
+.PD
+.SS Killing and Yanking
+.PP
+.PD 0
+.TP
+.B kill\-line (C\-k)
+Kill the text from the current cursor position 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.
+.\" 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 the
+cursor is. By default, this is unbound.
+.TP
+.B kill\-word (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 \fBforward\-word\fP.
+.TP
+.B backward\-kill\-word (M\-Rubout)
+Kill the word behind the cursor. Word boundaries are the same as
+those used by \fBbackward\-word\fP.
+.TP
+.B unix\-word\-rubout (C\-w)
+Kill the word behind the cursor, using white space as a word boundary.
+The word boundaries are different from
+.BR backward\-kill\-word .
+.TP
+.B delete\-horizontal\-space
+Delete all spaces and tabs around point. By default, this is unbound.
+.TP
+.B yank (C\-y)
+Yank the top of the kill ring into the buffer at the cursor.
+.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
+Each time this is executed, the argument count is multiplied by four.
+The argument count is initially one, so executing this function the
+first time makes the argument count four. By default, this is not
+bound to a key.
+.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
+Insert all completions of the text before point
+that would have been generated by
+\fBpossible\-completions\fP. By default, this
+is not bound to a key.
+.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 save 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 your init 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, ...)
+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 typing 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 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 emacs\-editing\-mode (C\-e)
+When in
+.B vi
+editing 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 8th bit set are written as M-<character>, 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
+.I 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
+.IR 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
+.I 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-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-_" -> undo
+"\^ " to "/" -> self-insert
+"0" to "9" -> self-insert
+":" to "~" -> self-insert
+"C-?" -> backward-delete-char
+.PP
+Emacs Meta bindings
+.sp
+"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-&" -> tilde-expand
+"M--" -> digit-argument
+"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->" -> 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-O" -> arrow-key-prefix
+"M-P" -> non-incremental-reverse-search-history
+"M-R" -> revert-line
+"M-T" -> transpose-words
+"M-U" -> upcase-word
+"M-Y" -> yank-pop
+"M-C-Y" -> yank-nth-arg
+"M-C-?" -> backward-delete-word
+.PP
+Emacs Control-X bindings
+.sp
+"C-XC-G" -> abort
+"C-XC-R" -> re-read-init-file
+"C-XC-U" -> undo
+"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-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-movement-mode
+"\^ " 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-[" -> abort
+"\^ " -> forward-char
+"#" -> vi-comment
+"$" -> end-of-line
+"%" -> vi-match
+"&" -> vi-tilde-expand
+"*" -> vi-complete
+"+" -> down-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
+"@" -> is undefined
+"A" -> vi-append-eol
+"B" -> vi-prev-word
+"C" -> vi-change-to
+"D" -> vi-delete-to
+"E" -> vi-end-word
+"F" -> vi-char-search
+"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
+"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
+"n" -> vi-search-again
+"r" -> vi-change-char
+"s" -> vi-subst
+"t" -> vi-char-search
+"u" -> 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
+.RS
+Brian Fox, Free Software Foundation (primary author)
+.br
+bfox@ai.MIT.Edu
+.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 \fIbash\-maintainers\fP@\fIprep.ai.MIT.Edu\fP.
+If you have a fix, you are welcome to mail that
+as well! Suggestions and `philosophical' bug reports may be mailed
+to \fPbug-bash\fP@\fIprep.ai.MIT.Edu\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/gnu/lib/libreadline/readline.c b/gnu/lib/libreadline/readline.c
new file mode 100644
index 0000000..59fbc32
--- /dev/null
+++ b/gnu/lib/libreadline/readline.c
@@ -0,0 +1,3539 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+#include <signal.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include <setjmp.h>
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+#if defined (GWINSZ_IN_SYS_IOCTL) || (defined (VSTATUS) && !defined (SunOS4))
+# include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL || VSTATUS */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+/* 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. */
+
+/* Functions imported from other files in the library. */
+extern char *tgetstr ();
+extern void rl_prep_terminal (), rl_deprep_terminal ();
+
+extern void _rl_bind_if_unbound ();
+
+/* External redisplay functions and variables from display.c */
+extern void _rl_move_vert ();
+extern void _rl_update_final ();
+
+extern void _rl_erase_at_end_of_line ();
+extern void _rl_move_cursor_relative ();
+
+extern int _rl_vis_botlin;
+extern int _rl_last_c_pos;
+extern int _rl_horizontal_scroll_mode;
+extern int rl_display_fixed;
+extern char *rl_display_prompt;
+
+/* Variables imported from complete.c. */
+extern char *rl_completer_word_break_characters;
+extern char *rl_basic_word_break_characters;
+extern int rl_completion_query_items;
+extern int rl_complete_with_tilde_expansion;
+
+#if defined (VI_MODE)
+extern void _rl_vi_set_last ();
+extern void _rl_vi_reset_last ();
+extern void _rl_vi_done_inserting ();
+#endif /* VI_MODE */
+
+/* Forward declarations used in this file. */
+void _rl_free_history_entry ();
+
+int _rl_dispatch ();
+void _rl_set_screen_size ();
+int _rl_output_character_function ();
+
+static char *readline_internal ();
+static void readline_initialize_everything ();
+static int init_terminal_io ();
+static void start_using_history ();
+static void bind_arrow_keys ();
+
+#if !defined (__GO32__)
+static void readline_default_bindings ();
+#endif /* !__GO32__ */
+
+#if defined (__GO32__)
+# include <sys/pc.h>
+# undef HANDLE_SIGNALS
+#endif /* __GO32__ */
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+
+/* **************************************************************** */
+/* */
+/* Line editing input utility */
+/* */
+/* **************************************************************** */
+
+static char *LibraryVersion = "2.0";
+
+/* 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;
+
+/* Non-zero if the previous command was a kill command. */
+static int 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 = 0;
+
+/* If non-zero, this program is running in an EMACS buffer. */
+static int running_in_emacs = 0;
+
+/* 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. */
+Function *rl_last_func = (Function *)NULL;
+
+/* Top level environment for readline_internal (). */
+static jmp_buf readline_top_level;
+
+/* The streams we interact with. */
+static FILE *in_stream, *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. */
+int readline_echoing_p = 1;
+
+/* Current prompt. */
+char *rl_prompt;
+int rl_visible_prompt_length = 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 () prints the first prompt. */
+Function *rl_startup_hook = (Function *)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. */
+char *rl_terminal_name = (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;
+
+/* Line buffer and maintenence. */
+char *rl_line_buffer = (char *)NULL;
+int rl_line_buffer_len = 0;
+#define DEFAULT_BUFFER_SIZE 256
+
+/* Forward declarations used by the display and termcap code. */
+int term_xn;
+int screenwidth, screenheight, screenchars;
+
+
+/* **************************************************************** */
+/* */
+/* `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 save keys that we dispatch on in a kbd macro. */
+static int defining_kbd_macro = 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;
+
+/* Non-zero tells rl_delete_text and rl_insert_text to not add to
+ the undo list. */
+static int doing_an_undo = 0;
+
+/* **************************************************************** */
+/* */
+/* Top Level Functions */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means treat 0200 bit in terminal input as Meta bit. */
+int _rl_meta_flag = 0; /* Forward declaration */
+
+/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means
+ none. A return value of NULL means that EOF was encountered. */
+char *
+readline (prompt)
+ char *prompt;
+{
+ char *value;
+
+ rl_prompt = prompt;
+
+ /* If we are at EOF return a NULL string. */
+ if (rl_pending_input == EOF)
+ {
+ rl_pending_input = 0;
+ return ((char *)NULL);
+ }
+
+ rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
+
+ rl_initialize ();
+ rl_prep_terminal (_rl_meta_flag);
+
+#if defined (HANDLE_SIGNALS)
+ rl_set_signals ();
+#endif
+
+ value = readline_internal ();
+ rl_deprep_terminal ();
+
+#if defined (HANDLE_SIGNALS)
+ rl_clear_signals ();
+#endif
+
+ return (value);
+}
+
+/* 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 lastc, c, eof_found;
+
+ in_stream = rl_instream;
+ out_stream = rl_outstream;
+
+ lastc = -1;
+ eof_found = 0;
+
+ if (rl_startup_hook)
+ (*rl_startup_hook) ();
+
+ if (!readline_echoing_p)
+ {
+ if (rl_prompt)
+ {
+ fprintf (out_stream, "%s", rl_prompt);
+ fflush (out_stream);
+ }
+ }
+ else
+ {
+ rl_on_new_line ();
+ rl_redisplay ();
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ rl_vi_insertion_mode ();
+#endif /* VI_MODE */
+ }
+
+ while (!rl_done)
+ {
+ int lk = last_command_was_kill;
+ int code;
+
+ code = setjmp (readline_top_level);
+
+ if (code)
+ rl_redisplay ();
+
+ if (!rl_pending_input)
+ {
+ /* Then initialize the argument and number of keys read. */
+ rl_init_argument ();
+ rl_key_sequence_length = 0;
+ }
+
+ c = rl_read_key ();
+
+ /* EOF typed to a non-blank line is a <NL>. */
+ 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)
+ {
+ eof_found = 1;
+ break;
+ }
+
+ lastc = c;
+ _rl_dispatch (c, _rl_keymap);
+
+ /* If there was no change in 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)
+ {
+ if (lk == last_command_was_kill)
+ 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_done)
+ rl_redisplay ();
+ }
+
+ /* Restore the original of this history line, iff the line that we
+ are editing was originally in the history, AND the line has changed. */
+ {
+ HIST_ENTRY *entry = current_history ();
+
+ if (entry && rl_undo_list)
+ {
+ char *temp = savestring (the_line);
+ rl_revert_line ();
+ entry = replace_history_entry (where_history (), the_line,
+ (HIST_ENTRY *)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)
+ free_undo_list ();
+
+ if (eof_found)
+ return (char *)NULL;
+ else
+ return (savestring (the_line));
+}
+
+/* **************************************************************** */
+/* */
+/* Character Input Buffering */
+/* */
+/* **************************************************************** */
+
+static int pop_index = 0, push_index = 0, ibuffer_len = 511;
+static unsigned char ibuffer[512];
+
+/* Non-null means it is a pointer to a function to run while waiting for
+ character input. */
+Function *rl_event_hook = (Function *)NULL;
+
+#define any_typein (push_index != pop_index)
+
+/* Add KEY to the buffer of characters to be read. */
+rl_stuff_char (key)
+ int key;
+{
+ if (key == EOF)
+ {
+ key = NEWLINE;
+ rl_pending_input = EOF;
+ }
+ ibuffer[push_index++] = key;
+ if (push_index >= ibuffer_len)
+ push_index = 0;
+ return push_index;
+}
+
+/* Return the amount of space available in the
+ buffer for stuffing characters. */
+int
+ibuffer_space ()
+{
+ if (pop_index > push_index)
+ return (pop_index - push_index);
+ 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. */
+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. */
+void
+rl_gather_tyi ()
+{
+#if defined (__GO32__)
+ char input;
+
+ if (isatty (0))
+ {
+ int i = rl_getc ();
+
+ if (i != EOF)
+ rl_stuff_char (i);
+ }
+ else if (kbhit () && ibuffer_space ())
+ rl_stuff_char (getkey ());
+#else /* !__GO32__ */
+
+ int tty = fileno (in_stream);
+ register int tem, result = -1;
+ int chars_avail;
+ char input;
+
+#if defined (FIONREAD)
+ result = ioctl (tty, FIONREAD, &chars_avail);
+#endif
+
+#if defined (O_NDELAY)
+ if (result == -1)
+ {
+ int flags;
+
+ flags = fcntl (tty, F_GETFL, 0);
+
+ fcntl (tty, F_SETFL, (flags | O_NDELAY));
+ chars_avail = read (tty, &input, 1);
+
+ fcntl (tty, F_SETFL, flags);
+ if (chars_avail == -1 && errno == EAGAIN)
+ return;
+ }
+#endif /* O_NDELAY */
+
+ /* If there's nothing available, don't waste time trying to read
+ something. */
+ if (chars_avail == 0)
+ return;
+
+ 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 (in_stream));
+ }
+ else
+ {
+ if (chars_avail)
+ rl_stuff_char (input);
+ }
+#endif /* !__GO32__ */
+}
+
+static int next_macro_key ();
+/* 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_pending_input = 0;
+ }
+ else
+ {
+ /* If input is coming from a macro, then use that. */
+ if (c = 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))
+ {
+ (*rl_event_hook) ();
+ rl_gather_tyi ();
+ }
+ }
+ else
+ {
+ if (!rl_get_char (&c))
+ c = rl_getc (in_stream);
+ }
+ }
+
+ return (c);
+}
+
+/* Found later in this file. */
+static void add_macro_char (), with_macro_input ();
+
+/* 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;
+{
+ int r = 0;
+
+ if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
+ {
+ if (map[ESC].type == ISKMAP)
+ {
+ if (defining_kbd_macro)
+ add_macro_char (ESC);
+ map = FUNCTION_TO_KEYMAP (map, ESC);
+ key = UNMETA (key);
+ rl_key_sequence_length += 2;
+ return (_rl_dispatch (key, map));
+ }
+ else
+ ding ();
+ return 0;
+ }
+
+ if (defining_kbd_macro)
+ add_macro_char (key);
+
+ switch (map[key].type)
+ {
+ case ISFUNC:
+ {
+ Function *func = map[key].function;
+
+ if (func != (Function *)NULL)
+ {
+ /* Special case rl_do_lowercase_version (). */
+ if (func == rl_do_lowercase_version)
+ return (_rl_dispatch (to_lower (key), map));
+
+ r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
+
+ /* 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)
+ rl_last_func = map[key].function;
+ }
+ else
+ {
+ rl_abort ();
+ return -1;
+ }
+ }
+ break;
+
+ case ISKMAP:
+ if (map[key].function != (Function *)NULL)
+ {
+ int newkey;
+
+ rl_key_sequence_length++;
+ newkey = rl_read_key ();
+ r = _rl_dispatch (newkey, FUNCTION_TO_KEYMAP (map, key));
+ }
+ else
+ {
+ rl_abort ();
+ return -1;
+ }
+ break;
+
+ case ISMACR:
+ if (map[key].function != (Function *)NULL)
+ {
+ char *macro;
+
+ macro = savestring ((char *)map[key].function);
+ 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);
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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. */
+static char *executing_macro = (char *)NULL;
+
+/* The offset in the above string to the next character to be read. */
+static int executing_macro_index = 0;
+
+/* 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 = 0;
+
+/* The index at which characters are being added to current_macro. */
+static int current_macro_index = 0;
+
+/* 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. */
+struct saved_macro *macro_list = (struct saved_macro *)NULL;
+
+/* Forward declarations of static functions. Thank you C. */
+static void push_executing_macro (), pop_executing_macro ();
+
+/* This one has to be declared earlier in the file. */
+/* static void add_macro_char (); */
+
+/* Set up to read subsequent input from STRING.
+ STRING is free ()'ed when we are done with it. */
+static void
+with_macro_input (string)
+ char *string;
+{
+ push_executing_macro ();
+ executing_macro = string;
+ executing_macro_index = 0;
+}
+
+/* Return the next character available from a macro, or 0 if
+ there are no macro characters. */
+static int
+next_macro_key ()
+{
+ if (!executing_macro)
+ return (0);
+
+ if (!executing_macro[executing_macro_index])
+ {
+ pop_executing_macro ();
+ return (next_macro_key ());
+ }
+
+ return (executing_macro[executing_macro_index++]);
+}
+
+/* Save the currently executing macro on a stack of saved macros. */
+static void
+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 = executing_macro;
+
+ macro_list = saver;
+}
+
+/* Discard the current macro, replacing it with the one
+ on the top of the stack of saved macros. */
+static void
+pop_executing_macro ()
+{
+ if (executing_macro)
+ free (executing_macro);
+
+ executing_macro = (char *)NULL;
+ executing_macro_index = 0;
+
+ if (macro_list)
+ {
+ struct saved_macro *disposer = macro_list;
+ executing_macro = macro_list->string;
+ executing_macro_index = macro_list->sindex;
+ macro_list = macro_list->next;
+ free (disposer);
+ }
+}
+
+/* Add a character to the macro being built. */
+static void
+add_macro_char (c)
+ int c;
+{
+ if (current_macro_index + 1 >= current_macro_size)
+ {
+ if (!current_macro)
+ current_macro = xmalloc (current_macro_size = 25);
+ else
+ current_macro = xrealloc (current_macro, current_macro_size += 25);
+ }
+
+ current_macro[current_macro_index++] = c;
+ current_macro[current_macro_index] = '\0';
+}
+
+/* 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. */
+rl_start_kbd_macro (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ if (defining_kbd_macro)
+ {
+ rl_abort ();
+ return -1;
+ }
+
+ if (rl_explicit_arg)
+ {
+ if (current_macro)
+ with_macro_input (savestring (current_macro));
+ }
+ else
+ current_macro_index = 0;
+
+ defining_kbd_macro = 1;
+ 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. */
+rl_end_kbd_macro (count, ignore)
+ int count, ignore;
+{
+ if (!defining_kbd_macro)
+ {
+ rl_abort ();
+ return -1;
+ }
+
+ current_macro_index -= (rl_key_sequence_length - 1);
+ current_macro[current_macro_index] = '\0';
+
+ defining_kbd_macro = 0;
+
+ return (rl_call_last_kbd_macro (--count, 0));
+}
+
+/* Execute the most recently defined keyboard macro.
+ COUNT says how many times to execute it. */
+rl_call_last_kbd_macro (count, ignore)
+ int count, ignore;
+{
+ if (!current_macro)
+ rl_abort ();
+
+ if (defining_kbd_macro)
+ {
+ ding (); /* no recursive macros */
+ current_macro[--current_macro_index] = '\0'; /* erase this char */
+ return 0;
+ }
+
+ while (count--)
+ with_macro_input (savestring (current_macro));
+ return 0;
+}
+
+void
+_rl_kill_kbd_macro ()
+{
+ if (current_macro)
+ {
+ free (current_macro);
+ current_macro = (char *) NULL;
+ }
+ current_macro_size = current_macro_index = 0;
+
+ if (executing_macro)
+ {
+ free (executing_macro);
+ executing_macro = (char *) NULL;
+ }
+ executing_macro_index = 0;
+
+ defining_kbd_macro = 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Initializations */
+/* */
+/* **************************************************************** */
+
+/* Initliaze readline (and terminal if not already). */
+rl_initialize ()
+{
+ /* If we have never been called before, initialize the
+ terminal and data structures. */
+ if (!rl_initialized)
+ {
+ readline_initialize_everything ();
+ rl_initialized++;
+ }
+
+ /* Initalize the current line information. */
+ rl_point = rl_end = 0;
+ the_line = rl_line_buffer;
+ the_line[0] = 0;
+
+ /* We aren't done yet. We haven't even gotten started yet! */
+ rl_done = 0;
+
+ /* Tell the history routines what is going on. */
+ 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 = (Function *)NULL;
+
+ /* Parsing of key-bindings begins in an enabled state. */
+ _rl_parsing_conditionalized_out = 0;
+
+ return 0;
+}
+
+/* Initialize the entire state of the world. */
+static void
+readline_initialize_everything ()
+{
+ char *t, *t1;
+
+ /* Find out if we are running in Emacs. */
+ running_in_emacs = getenv ("EMACS") != (char *)0;
+
+ /* 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 in_stream and out_stream immediately. These values may change,
+ but they may also be used before readline_internal () is called. */
+ in_stream = rl_instream;
+ out_stream = rl_outstream;
+
+ /* Allocate data structures. */
+ if (!rl_line_buffer)
+ rl_line_buffer = xmalloc (rl_line_buffer_len = DEFAULT_BUFFER_SIZE);
+
+ /* Initialize the terminal interface. */
+ init_terminal_io ((char *)NULL);
+
+#if !defined (__GO32__)
+ /* Bind tty characters to readline functions. */
+ readline_default_bindings ();
+#endif /* !__GO32__ */
+
+ /* Initialize the function names. */
+ rl_initialize_funmap ();
+
+ /* Check for LC_CTYPE and use its value to decide the defaults for
+ 8-bit character input and output. */
+ t = getenv ("LC_CTYPE");
+ t1 = getenv ("LANG");
+ if (t && (strstr (t, "8859-1") != NULL || strstr (t, "8859_1") != NULL ||
+ strstr (t, "KOI8-R") != NULL || strstr (t, "koi8-r") != NULL) ||
+ t1 && (strstr (t1, "8859-1") != NULL || strstr (t1, "8859_1") != NULL ||
+ strstr (t1, "KOI8-R") != NULL || strstr (t1, "koi8-r") != NULL))
+ {
+ _rl_meta_flag = 1;
+ _rl_convert_meta_chars_to_ascii = 0;
+ _rl_output_meta_chars = 1;
+ }
+
+ /* Read in the init file. */
+ rl_read_init_file ((char *)NULL);
+
+ /* XXX */
+ if (_rl_horizontal_scroll_mode && term_xn)
+ {
+ screenwidth--;
+ screenchars -= 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 ();
+
+ /* 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 ()
+{
+ rltty_set_default_bindings (_rl_keymap);
+}
+
+static void
+bind_arrow_keys_internal ()
+{
+ Function *f;
+
+ f = rl_function_of_keyseq ("\033[A", _rl_keymap, (int *)NULL);
+ if (!f || f == rl_do_lowercase_version)
+ {
+ _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);
+ _rl_bind_if_unbound ("\033[D", rl_backward);
+ }
+
+ f = rl_function_of_keyseq ("\033OA", _rl_keymap, (int *)NULL);
+ if (!f || f == rl_do_lowercase_version)
+ {
+ _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);
+ _rl_bind_if_unbound ("\033OD", rl_backward);
+ }
+}
+
+/* Try and bind the common arrow key prefix 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 ()
+{
+ Keymap xkeymap;
+
+ xkeymap = _rl_keymap;
+
+ _rl_keymap = emacs_standard_keymap;
+ bind_arrow_keys_internal ();
+
+#if defined (VI_MODE)
+ _rl_keymap = vi_movement_keymap;
+ bind_arrow_keys_internal ();
+#endif
+
+ _rl_keymap = xkeymap;
+}
+
+
+/* **************************************************************** */
+/* */
+/* Numeric Arguments */
+/* */
+/* **************************************************************** */
+
+/* Handle C-u style numeric args, as well as M--, and M-digits. */
+static int
+rl_digit_loop ()
+{
+ int key, c;
+
+ while (1)
+ {
+ rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
+ key = c = rl_read_key ();
+
+ if (_rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
+ {
+ rl_numeric_arg *= 4;
+ continue;
+ }
+ c = UNMETA (c);
+ if (digit_p (c))
+ {
+ if (rl_explicit_arg)
+ rl_numeric_arg = (rl_numeric_arg * 10) + (c - '0');
+ else
+ rl_numeric_arg = (c - '0');
+ rl_explicit_arg = 1;
+ }
+ else
+ {
+ if (c == '-' && !rl_explicit_arg)
+ {
+ rl_numeric_arg = 1;
+ rl_arg_sign = -1;
+ }
+ else
+ {
+ rl_clear_message ();
+ return (_rl_dispatch (key, _rl_keymap));
+ }
+ }
+ }
+ return 0;
+}
+
+/* Add the current digit to the argument in progress. */
+rl_digit_argument (ignore, key)
+ int ignore, key;
+{
+ rl_pending_input = key;
+ return (rl_digit_loop ());
+}
+
+/* What to do when you abort reading an argument. */
+rl_discard_argument ()
+{
+ ding ();
+ rl_clear_message ();
+ rl_init_argument ();
+ return 0;
+}
+
+/* Create a default argument. */
+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. */
+rl_universal_argument ()
+{
+ rl_numeric_arg *= 4;
+ return (rl_digit_loop ());
+}
+
+/* **************************************************************** */
+/* */
+/* Terminal and Termcap */
+/* */
+/* **************************************************************** */
+
+static char *term_buffer = (char *)NULL;
+static char *term_string_buffer = (char *)NULL;
+
+static int tcap_initialized = 0;
+
+/* Non-zero means this terminal can't really do anything. */
+int dumb_term = 0;
+/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
+ Unfortunately, PC is a global variable used by the termcap library. */
+#undef PC
+
+#if !defined (__linux__)
+/* If this causes problems, add back the `extern'. */
+/*extern*/ char PC, *BC, *UP;
+#endif /* __linux__ */
+
+/* Some strings to control terminal actions. These are output by tputs (). */
+char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
+char *term_pc;
+
+/* Non-zero if we determine that the terminal can do character insertion. */
+int terminal_can_insert = 0;
+
+/* How to insert characters. */
+char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
+
+/* How to delete characters. */
+char *term_dc, *term_DC;
+
+#if defined (HACK_TERMCAP_MOTION)
+char *term_forward_char;
+#endif /* HACK_TERMCAP_MOTION */
+
+/* How to go up a line. */
+char *term_up;
+
+/* A visible bell, if the terminal can be made to flash the screen. */
+char *visible_bell;
+
+/* Non-zero means that this terminal has a meta key. */
+int term_has_meta;
+
+/* The string to write to turn on the meta key, if this term has one. */
+char *term_mm;
+
+/* The string to write to turn off the meta key, if this term has one. */
+char *term_mo;
+
+/* The key sequences output by the arrow keys, if this terminal has any. */
+char *term_ku, *term_kd, *term_kr, *term_kl;
+
+/* How to initialize and reset the arrow keys, if this terminal has any. */
+char *term_ks, *term_ke;
+
+/* Re-initialize the terminal considering that the TERM/TERMCAP variable
+ has changed. */
+rl_reset_terminal (terminal_name)
+ char *terminal_name;
+{
+ init_terminal_io (terminal_name);
+ return 0;
+}
+
+/* Set 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_set_screen_size (tty, ignore_env)
+ int tty, ignore_env;
+{
+#if defined (TIOCGWINSZ)
+ struct winsize window_size;
+#endif /* TIOCGWINSZ */
+
+#if defined (TIOCGWINSZ)
+ if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
+ {
+ screenwidth = (int) window_size.ws_col;
+ screenheight = (int) window_size.ws_row;
+ }
+#endif /* TIOCGWINSZ */
+
+ /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
+ is unset. */
+ if (screenwidth <= 0)
+ {
+ char *sw;
+
+ if (!ignore_env && (sw = getenv ("COLUMNS")))
+ screenwidth = atoi (sw);
+
+ if (screenwidth <= 0 && term_string_buffer)
+ screenwidth = tgetnum ("co");
+ }
+
+ /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
+ is unset. */
+ if (screenheight <= 0)
+ {
+ char *sh;
+
+ if (!ignore_env && (sh = getenv ("LINES")))
+ screenheight = atoi (sh);
+
+ if (screenheight <= 0 && term_string_buffer)
+ screenheight = tgetnum ("li");
+ }
+
+ /* If all else fails, default to 80x24 terminal. */
+ if (screenwidth <= 1)
+ screenwidth = 80;
+
+ if (screenheight <= 0)
+ screenheight = 24;
+
+#if defined (SHELL)
+ /* If we're being compiled as part of bash, set the environment
+ variables $LINES and $COLUMNS to new values. */
+ set_lines_and_columns (screenheight, screenwidth);
+#endif
+
+ if (!term_xn)
+ screenwidth--;
+
+ screenchars = screenwidth * screenheight;
+}
+
+struct _tc_string {
+ 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[] =
+{
+ "DC", &term_DC,
+ "IC", &term_IC,
+ "ce", &term_clreol,
+ "cl", &term_clrpag,
+ "cr", &term_cr,
+ "dc", &term_dc,
+ "ei", &term_ei,
+ "ic", &term_ic,
+ "im", &term_im,
+ "kd", &term_kd,
+ "kl", &term_kl,
+ "kr", &term_kr,
+ "ku", &term_ku,
+ "ks", &term_ks,
+ "ke", &term_ke,
+ "le", &term_backspace,
+ "mm", &term_mm,
+ "mo", &term_mo,
+#if defined (HACK_TERMCAP_MOTION)
+ "nd", &term_forward_char,
+#endif
+ "pc", &term_pc,
+ "up", &term_up,
+ "vb", &visible_bell,
+};
+
+#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;
+{
+ register int i;
+
+ for (i = 0; i < NUM_TC_STRINGS; i++)
+ *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
+ tcap_initialized = 1;
+}
+
+static int
+init_terminal_io (terminal_name)
+ char *terminal_name;
+{
+#if defined (__GO32__)
+ screenwidth = ScreenCols ();
+ screenheight = ScreenRows ();
+ screenchars = screenwidth * screenheight;
+ term_cr = "\r";
+ term_im = term_ei = term_ic = term_IC = (char *)NULL;
+ term_up = term_dc = term_DC = visible_bell = (char *)NULL;
+
+ /* Does the __GO32__ have a meta key? I don't know. */
+ term_has_meta = 0;
+ term_mm = term_mo = (char *)NULL;
+
+ /* It probably has arrow keys, but I don't know what they are. */
+ term_ku = term_kd = term_kr = term_kl = (char *)NULL;
+
+#if defined (HACK_TERMCAP_MOTION)
+ term_forward_char = (char *)NULL;
+#endif /* HACK_TERMCAP_MOTION */
+ terminal_can_insert = term_xn = 0;
+ return;
+#else /* !__GO32__ */
+
+ char *term, *buffer;
+ int tty;
+ Keymap xkeymap;
+
+ term = terminal_name ? terminal_name : getenv ("TERM");
+
+ if (!term_string_buffer)
+ term_string_buffer = xmalloc (2048);
+
+ if (!term_buffer)
+ term_buffer = xmalloc (2048);
+
+ buffer = term_string_buffer;
+
+ term_clrpag = term_cr = term_clreol = (char *)NULL;
+
+ if (!term)
+ term = "dumb";
+
+ if (tgetent (term_buffer, term) <= 0)
+ {
+ dumb_term = 1;
+ screenwidth = 79;
+ screenheight = 24;
+ screenchars = 79 * 24;
+ term_cr = "\r";
+ term_im = term_ei = term_ic = term_IC = (char *)NULL;
+ term_up = term_dc = term_DC = visible_bell = (char *)NULL;
+ term_ku = term_kd = term_kl = term_kr = (char *)NULL;
+#if defined (HACK_TERMCAP_MOTION)
+ term_forward_char = (char *)NULL;
+#endif
+ terminal_can_insert = 0;
+ return 0;
+ }
+
+ get_term_capabilities (&buffer);
+
+ /* Set up the variables that the termcap library expects the application
+ to provide. */
+ PC = term_pc ? *term_pc : 0;
+ BC = term_backspace;
+ UP = term_up;
+
+ if (!term_cr)
+ term_cr = "\r";
+
+ if (rl_instream)
+ tty = fileno (rl_instream);
+ else
+ tty = 0;
+
+ screenwidth = screenheight = 0;
+
+ term_xn = tgetflag ("am") && tgetflag ("xn");
+
+ _rl_set_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... */
+ terminal_can_insert = (term_IC || term_im || 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)
+ {
+ term_mm = (char *)NULL;
+ term_mo = (char *)NULL;
+ }
+
+ /* Attempt to find and bind the arrow keys. Do not override already
+ bound keys in an overzealous attempt, however. */
+ xkeymap = _rl_keymap;
+
+ _rl_keymap = emacs_standard_keymap;
+ _rl_bind_if_unbound (term_ku, rl_get_previous_history);
+ _rl_bind_if_unbound (term_kd, rl_get_next_history);
+ _rl_bind_if_unbound (term_kr, rl_forward);
+ _rl_bind_if_unbound (term_kl, rl_backward);
+
+#if defined (VI_MODE)
+ _rl_keymap = vi_movement_keymap;
+ _rl_bind_if_unbound (term_ku, rl_get_previous_history);
+ _rl_bind_if_unbound (term_kd, rl_get_next_history);
+ _rl_bind_if_unbound (term_kr, rl_forward);
+ _rl_bind_if_unbound (term_kl, rl_backward);
+#endif /* VI_MODE */
+
+ _rl_keymap = xkeymap;
+
+#endif /* !__GO32__ */
+ return 0;
+}
+
+char *
+rl_get_termcap (cap)
+ 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);
+}
+
+/* A function for the use of tputs () */
+int
+_rl_output_character_function (c)
+ int c;
+{
+ return putc (c, out_stream);
+}
+
+/* Write COUNT characters from STRING to the output stream. */
+void
+_rl_output_some_chars (string, count)
+ char *string;
+ int count;
+{
+ fwrite (string, 1, count, out_stream);
+}
+
+/* Move the cursor back. */
+backspace (count)
+ int count;
+{
+ register int i;
+
+#if !defined (__GO32__)
+ if (term_backspace)
+ for (i = 0; i < count; i++)
+ tputs (term_backspace, 1, _rl_output_character_function);
+ else
+#endif /* !__GO32__ */
+ for (i = 0; i < count; i++)
+ putc ('\b', out_stream);
+ return 0;
+}
+
+/* Move to the start of the next line. */
+crlf ()
+{
+#if defined (NEW_TTY_DRIVER)
+ tputs (term_cr, 1, _rl_output_character_function);
+#endif /* NEW_TTY_DRIVER */
+ putc ('\n', out_stream);
+ return 0;
+}
+
+rl_tty_status (count, key)
+ int count, key;
+{
+#if defined (TIOCSTAT)
+ ioctl (1, TIOCSTAT, (char *)0);
+ rl_refresh_line ();
+#else
+ ding ();
+#endif
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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 allow_pathname_alphabetic_chars = 0;
+char *pathname_alphabetic_chars = "/-_=~.#$";
+
+int
+alphabetic (c)
+ int c;
+{
+ if (pure_alphabetic (c) || (digit_p (c)))
+ return (1);
+
+ if (allow_pathname_alphabetic_chars)
+ return (strchr (pathname_alphabetic_chars, c) != NULL);
+ else
+ return (0);
+}
+
+/* Ring the terminal bell. */
+int
+ding ()
+{
+ if (readline_echoing_p)
+ {
+#if !defined (__GO32__)
+ switch (_rl_bell_preference)
+ {
+ case NO_BELL:
+ default:
+ break;
+ case VISIBLE_BELL:
+ if (visible_bell)
+ {
+ tputs (visible_bell, 1, _rl_output_character_function);
+ break;
+ }
+ /* FALLTHROUGH */
+ case AUDIBLE_BELL:
+ fprintf (stderr, "\007");
+ fflush (stderr);
+ break;
+ }
+#else /* __GO32__ */
+ fprintf (stderr, "\007");
+ fflush (stderr);
+#endif /* __GO32__ */
+ return (0);
+ }
+ return (-1);
+}
+
+/* How to abort things. */
+rl_abort (count, key)
+ int count, key;
+{
+ ding ();
+ rl_clear_message ();
+ rl_init_argument ();
+ rl_pending_input = 0;
+
+ defining_kbd_macro = 0;
+ while (executing_macro)
+ pop_executing_macro ();
+
+ rl_last_func = (Function *)NULL;
+ longjmp (readline_top_level, 1);
+}
+
+/* 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)
+ {
+ int t = from;
+ from = to;
+ to = t;
+ }
+
+ length = to - from;
+ copy = xmalloc (1 + length);
+ strncpy (copy, the_line + 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 = xrealloc (rl_line_buffer, rl_line_buffer_len);
+ }
+
+ the_line = rl_line_buffer;
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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 () calls this
+ function. */
+rl_insert_text (string)
+ char *string;
+{
+ register int i, l = strlen (string);
+
+ if (rl_end + l >= rl_line_buffer_len)
+ rl_extend_line_buffer (rl_end + l);
+
+ for (i = rl_end; i >= rl_point; i--)
+ the_line[i + l] = the_line[i];
+ strncpy (the_line + rl_point, string, l);
+
+ /* Remember how to undo this if we aren't undoing something. */
+ if (!doing_an_undo)
+ {
+ /* 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;
+ the_line[rl_end] = '\0';
+ return l;
+}
+
+/* Delete the string between FROM and TO. FROM is
+ inclusive, TO is not. */
+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)
+ {
+ int t = from;
+ from = to;
+ to = t;
+ }
+
+ if (to > rl_end)
+ to = rl_end;
+
+ 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++)
+ the_line[i] = the_line[i + diff];
+
+ /* Remember how to undo this delete. */
+ if (!doing_an_undo)
+ rl_add_undo (UNDO_DELETE, from, to, text);
+ else
+ free (text);
+
+ rl_end -= diff;
+ the_line[rl_end] = '\0';
+ return (diff);
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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 characters. */
+rl_forward (count, key)
+ int count, key;
+{
+ if (count < 0)
+ rl_backward (-count);
+ else if (count > 0)
+ {
+ int end = rl_point + count;
+#if defined (VI_MODE)
+ int lend = rl_end - (rl_editing_mode == vi_mode);
+#else
+ int lend = rl_end;
+#endif
+
+ if (end > lend)
+ {
+ rl_point = lend;
+ ding ();
+ }
+ else
+ rl_point = end;
+ }
+ return 0;
+}
+
+/* Move backward COUNT characters. */
+rl_backward (count, key)
+ int count, key;
+{
+ if (count < 0)
+ rl_forward (-count);
+ else if (count > 0)
+ {
+ if (rl_point < count)
+ {
+ rl_point = 0;
+ ding ();
+ }
+ else
+ rl_point -= count;
+ }
+ return 0;
+}
+
+/* Move to the beginning of the line. */
+rl_beg_of_line (count, key)
+ int count, key;
+{
+ rl_point = 0;
+ return 0;
+}
+
+/* Move to the end of the line. */
+rl_end_of_line (count, key)
+ int count, key;
+{
+ rl_point = rl_end;
+ return 0;
+}
+
+/* Move forward a word. We do what Emacs does. */
+rl_forward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ {
+ rl_backward_word (-count);
+ return 0;
+ }
+
+ 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 = the_line[rl_point];
+ if (!alphabetic (c))
+ {
+ while (++rl_point < rl_end)
+ {
+ c = the_line[rl_point];
+ if (alphabetic (c))
+ break;
+ }
+ }
+ if (rl_point == rl_end)
+ return 0;
+ while (++rl_point < rl_end)
+ {
+ c = the_line[rl_point];
+ if (!alphabetic (c))
+ break;
+ }
+ --count;
+ }
+ return 0;
+}
+
+/* Move backward a word. We do what Emacs does. */
+rl_backward_word (count, key)
+ int count, key;
+{
+ int c;
+
+ if (count < 0)
+ {
+ rl_forward_word (-count);
+ return 0;
+ }
+
+ while (count)
+ {
+ if (!rl_point)
+ return 0;
+
+ /* Like rl_forward_word (), except that we look at the characters
+ just before point. */
+
+ c = the_line[rl_point - 1];
+ if (!alphabetic (c))
+ {
+ while (--rl_point)
+ {
+ c = the_line[rl_point - 1];
+ if (alphabetic (c))
+ break;
+ }
+ }
+
+ while (rl_point)
+ {
+ c = the_line[rl_point - 1];
+ if (!alphabetic (c))
+ break;
+ else
+ --rl_point;
+ }
+ --count;
+ }
+ return 0;
+}
+
+/* Clear the current line. Numeric argument to C-l does this. */
+rl_refresh_line ()
+{
+ int curr_line, 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 - screenwidth - rl_visible_prompt_length;
+ else
+ nleft = _rl_last_c_pos - screenwidth;
+
+ if (nleft > 0)
+ curr_line = 1 + nleft / screenwidth;
+ else
+ curr_line = 0;
+
+ _rl_move_vert (curr_line);
+ _rl_move_cursor_relative (0, the_line); /* XXX is this right */
+
+#if defined (__GO32__)
+ {
+ int row, col, width, row_start;
+
+ ScreenGetCursor (&row, &col);
+ width = ScreenCols ();
+ row_start = ScreenPrimary + (row * width);
+ memset (row_start + col, 0, (width - col) * 2);
+ }
+#else /* !__GO32__ */
+ if (term_clreol)
+ tputs (term_clreol, 1, _rl_output_character_function);
+#endif /* !__GO32__ */
+
+ 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. */
+rl_clear_screen (count, key)
+ int count, key;
+{
+ if (rl_explicit_arg)
+ {
+ rl_refresh_line ();
+ return 0;
+ }
+
+#if !defined (__GO32__)
+ if (term_clrpag)
+ tputs (term_clrpag, 1, _rl_output_character_function);
+ else
+#endif /* !__GO32__ */
+ crlf ();
+
+ rl_forced_update_display ();
+ rl_display_fixed = 1;
+
+ return 0;
+}
+
+rl_arrow_keys (count, c)
+ int count, c;
+{
+ int ch;
+
+ ch = rl_read_key ();
+
+ switch (to_upper (ch))
+ {
+ case 'A':
+ rl_get_previous_history (count);
+ break;
+
+ case 'B':
+ rl_get_next_history (count);
+ break;
+
+ case 'C':
+ rl_forward (count);
+ break;
+
+ case 'D':
+ rl_backward (count);
+ break;
+
+ default:
+ ding ();
+ }
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* Text commands */
+/* */
+/* **************************************************************** */
+
+/* Insert the character C at the current location, moving point forward. */
+rl_insert (count, c)
+ int count, c;
+{
+ register int i;
+ char *string;
+
+ if (count <= 0)
+ return 0;
+
+ /* If we can optimize, then do it. But don't let people crash
+ readline because of extra large arguments. */
+ if (count > 1 && count < 1024)
+ {
+ string = xmalloc (1 + count);
+
+ for (i = 0; i < count; i++)
+ string[i] = c;
+
+ string[i] = '\0';
+ rl_insert_text (string);
+ free (string);
+
+ return 0;
+ }
+
+ if (count > 1024)
+ {
+ int decreaser;
+ 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;
+ }
+
+ return 0;
+ }
+
+ /* 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 (any_typein)
+ {
+ int key = 0, t;
+
+ i = 0;
+ string = xmalloc (ibuffer_len + 1);
+ string[i++] = 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);
+ }
+ else
+ {
+ /* Inserting a single character. */
+ char str[2];
+
+ str[1] = '\0';
+ str[0] = c;
+ rl_insert_text (str);
+ }
+ return 0;
+}
+
+/* Insert the next typed character verbatim. */
+rl_quoted_insert (count, key)
+ int count, key;
+{
+ int c;
+
+ c = rl_read_key ();
+ return (rl_insert (count, c));
+}
+
+/* Insert a tab character. */
+rl_tab_insert (count, key)
+ int count, key;
+{
+ return (rl_insert (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. */
+rl_newline (count, key)
+ int count, key;
+{
+ rl_done = 1;
+
+#if defined (VI_MODE)
+ _rl_vi_done_inserting ();
+ _rl_vi_reset_last ();
+
+#endif /* VI_MODE */
+
+ if (readline_echoing_p)
+ _rl_update_final ();
+ return 0;
+}
+
+rl_clean_up_for_exit ()
+{
+ if (readline_echoing_p)
+ {
+ _rl_move_vert (_rl_vis_botlin);
+ _rl_vis_botlin = 0;
+ fflush (out_stream);
+ rl_restart_output ();
+ }
+ 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. */
+rl_do_lowercase_version (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ return 0;
+}
+
+/* Rubout the character behind point. */
+rl_rubout (count, key)
+ int count, key;
+{
+ if (count < 0)
+ {
+ rl_delete (-count);
+ return 0;
+ }
+
+ if (!rl_point)
+ {
+ ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ int orig_point = rl_point;
+ rl_backward (count);
+ rl_kill_text (orig_point, rl_point);
+ }
+ else
+ {
+ int c = the_line[--rl_point];
+ rl_delete_text (rl_point, rl_point + 1);
+
+ 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. */
+rl_delete (count, invoking_key)
+ int count, invoking_key;
+{
+ if (count < 0)
+ {
+ return (rl_rubout (-count));
+ }
+
+ if (rl_point == rl_end)
+ {
+ ding ();
+ return -1;
+ }
+
+ if (count > 1 || rl_explicit_arg)
+ {
+ int orig_point = rl_point;
+ rl_forward (count);
+ rl_kill_text (orig_point, rl_point);
+ rl_point = orig_point;
+ return 0;
+ }
+ else
+ return (rl_delete_text (rl_point, rl_point + 1));
+
+}
+
+/* Delete all spaces and tabs around point. */
+rl_delete_horizontal_space (count, ignore)
+ int count, ignore;
+{
+ int start = rl_point;
+
+ while (rl_point && whitespace (the_line[rl_point - 1]))
+ rl_point--;
+
+ start = rl_point;
+
+ while (rl_point < rl_end && whitespace (the_line[rl_point]))
+ rl_point++;
+
+ if (start != rl_point)
+ {
+ rl_delete_text (start, rl_point);
+ rl_point = start;
+ }
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* Kill commands */
+/* */
+/* **************************************************************** */
+
+/* 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. */
+rl_unix_word_rubout (count, key)
+ int count, key;
+{
+ if (!rl_point)
+ ding ();
+ else
+ {
+ int orig_point = rl_point;
+ if (count <= 0)
+ count = 1;
+
+ while (count--)
+ {
+ while (rl_point && whitespace (the_line[rl_point - 1]))
+ rl_point--;
+
+ while (rl_point && !whitespace (the_line[rl_point - 1]))
+ rl_point--;
+ }
+
+ rl_kill_text (orig_point, 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. */
+rl_unix_line_discard (count, key)
+ int count, key;
+{
+ if (!rl_point)
+ ding ();
+ else
+ {
+ rl_kill_text (rl_point, 0);
+ rl_point = 0;
+ }
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* Commands For Typos */
+/* */
+/* **************************************************************** */
+
+/* Random and interesting things in here. */
+
+/* **************************************************************** */
+/* */
+/* Changing Case */
+/* */
+/* **************************************************************** */
+
+/* The three kinds of things that we know how to do. */
+#define UpCase 1
+#define DownCase 2
+#define CapCase 3
+
+static int rl_change_case ();
+
+/* Uppercase the word at point. */
+rl_upcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, UpCase));
+}
+
+/* Lowercase the word at point. */
+rl_downcase_word (count, key)
+ int count, key;
+{
+ return (rl_change_case (count, DownCase));
+}
+
+/* Upcase the first letter, downcase the rest. */
+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 = rl_point, end;
+ int state = 0;
+
+ rl_forward_word (count);
+ end = rl_point;
+
+ if (count < 0)
+ {
+ int temp = start;
+ start = end;
+ end = temp;
+ }
+
+ /* We are going to modify some text, so let's prepare to undo it. */
+ rl_modifying (start, end);
+
+ for (; start < end; start++)
+ {
+ switch (op)
+ {
+ case UpCase:
+ the_line[start] = to_upper (the_line[start]);
+ break;
+
+ case DownCase:
+ the_line[start] = to_lower (the_line[start]);
+ break;
+
+ case CapCase:
+ if (state == 0)
+ {
+ the_line[start] = to_upper (the_line[start]);
+ state = 1;
+ }
+ else
+ {
+ the_line[start] = to_lower (the_line[start]);
+ }
+ if (!pure_alphabetic (the_line[start]))
+ state = 0;
+ break;
+
+ default:
+ ding ();
+ return -1;
+ }
+ }
+ rl_point = end;
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Transposition */
+/* */
+/* **************************************************************** */
+
+/* Transpose the words at point. */
+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);
+ w2_end = rl_point;
+ rl_backward_word (1);
+ w2_beg = rl_point;
+ rl_backward_word (count);
+ w1_beg = rl_point;
+ rl_forward_word (1);
+ 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))
+ {
+ 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. */
+rl_transpose_chars (count, key)
+ int count, key;
+{
+ char dummy[2];
+
+ if (!count)
+ return 0;
+
+ if (!rl_point || rl_end < 2)
+ {
+ ding ();
+ return -1;
+ }
+
+ rl_begin_undo_group ();
+
+ if (rl_point == rl_end)
+ {
+ --rl_point;
+ count = 1;
+ }
+ rl_point--;
+
+ dummy[0] = the_line[rl_point];
+ dummy[1] = '\0';
+
+ rl_delete_text (rl_point, rl_point + 1);
+
+ rl_point += count;
+ if (rl_point > rl_end)
+ rl_point = rl_end;
+ else if (rl_point < 0)
+ rl_point = 0;
+ rl_insert_text (dummy);
+
+ rl_end_undo_group ();
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* Undo, and Undoing */
+/* */
+/* **************************************************************** */
+
+/* The current undo list for THE_LINE. */
+UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
+
+/* 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
+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 = 0;
+
+undo_thing:
+ if (!rl_undo_list)
+ return (0);
+
+ doing_an_undo = 1;
+
+ switch (rl_undo_list->what) {
+
+ /* Undoing deletes means inserting some text. */
+ case UNDO_DELETE:
+ rl_point = rl_undo_list->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 (rl_undo_list->start, rl_undo_list->end);
+ rl_point = rl_undo_list->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
+ ding ();
+ break;
+ }
+
+ doing_an_undo = 0;
+
+ release = rl_undo_list;
+ rl_undo_list = rl_undo_list->next;
+ free (release);
+
+ if (waiting_for_begin)
+ goto undo_thing;
+
+ 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);
+ 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);
+ return 0;
+}
+
+/* Save an undo entry for the text from START to END. */
+rl_modifying (start, end)
+ int start, end;
+{
+ if (start > end)
+ {
+ int t = start;
+ start = end;
+ end = t;
+ }
+
+ 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)
+ 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
+ {
+ ding ();
+ break;
+ }
+ }
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* History Utilities */
+/* */
+/* **************************************************************** */
+
+/* We already have a history library, and that is what we use to control
+ the history features of readline. However, 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 *saved_line_for_history = (HIST_ENTRY *)NULL;
+
+/* Set the history pointer back to the last entry in the history. */
+static void
+start_using_history ()
+{
+ using_history ();
+ if (saved_line_for_history)
+ _rl_free_history_entry (saved_line_for_history);
+
+ 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)
+ return;
+ if (entry->line)
+ free (entry->line);
+ free (entry);
+}
+
+/* Perhaps put back the current line if it has changed. */
+maybe_replace_line ()
+{
+ HIST_ENTRY *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 (), the_line, rl_undo_list);
+ free (temp->line);
+ free (temp);
+ }
+ return 0;
+}
+
+/* Put back the saved_line_for_history if there is one. */
+maybe_unsave_line ()
+{
+ if (saved_line_for_history)
+ {
+ int line_len;
+
+ line_len = strlen (saved_line_for_history->line);
+
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+
+ strcpy (the_line, saved_line_for_history->line);
+ rl_undo_list = (UNDO_LIST *)saved_line_for_history->data;
+ _rl_free_history_entry (saved_line_for_history);
+ saved_line_for_history = (HIST_ENTRY *)NULL;
+ rl_end = rl_point = strlen (the_line);
+ }
+ else
+ ding ();
+ return 0;
+}
+
+/* Save the current line in saved_line_for_history. */
+maybe_save_line ()
+{
+ if (!saved_line_for_history)
+ {
+ saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
+ saved_line_for_history->line = savestring (the_line);
+ saved_line_for_history->data = (char *)rl_undo_list;
+ }
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* History Commands */
+/* */
+/* **************************************************************** */
+
+/* Meta-< goes to the start of the history. */
+rl_beginning_of_history (count, key)
+ int count, key;
+{
+ return (rl_get_previous_history (1 + where_history ()));
+}
+
+/* Meta-> goes to the end of the history. (The current line). */
+rl_end_of_history (count, key)
+ int count, key;
+{
+ maybe_replace_line ();
+ using_history ();
+ maybe_unsave_line ();
+ return 0;
+}
+
+/* Move down to the next history line. */
+rl_get_next_history (count, key)
+ int count, key;
+{
+ HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
+
+ if (count < 0)
+ return (rl_get_previous_history (-count));
+
+ if (!count)
+ return 0;
+
+ maybe_replace_line ();
+
+ while (count)
+ {
+ temp = next_history ();
+ if (!temp)
+ break;
+ --count;
+ }
+
+ if (!temp)
+ maybe_unsave_line ();
+ else
+ {
+ int line_len;
+
+ line_len = strlen (temp->line);
+
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+
+ strcpy (the_line, temp->line);
+ rl_undo_list = (UNDO_LIST *)temp->data;
+ rl_end = rl_point = strlen (the_line);
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ rl_point = 0;
+#endif /* VI_MODE */
+ }
+ return 0;
+}
+
+/* Get the previous item out of our interactive history, making it the current
+ line. If there is no previous history, just ding. */
+rl_get_previous_history (count, key)
+ int count, key;
+{
+ HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL;
+ HIST_ENTRY *temp = (HIST_ENTRY *)NULL;
+
+ if (count < 0)
+ return (rl_get_next_history (-count));
+
+ if (!count)
+ return 0;
+
+ /* If we don't have a line saved, then save this one. */
+ maybe_save_line ();
+
+ /* If the current line has changed, save the changes. */
+ maybe_replace_line ();
+
+ while (count)
+ {
+ temp = previous_history ();
+ if (!temp)
+ break;
+ else
+ 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)
+ ding ();
+ else
+ {
+ int line_len;
+
+ line_len = strlen (temp->line);
+
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+
+ strcpy (the_line, temp->line);
+ rl_undo_list = (UNDO_LIST *)temp->data;
+ rl_end = rl_point = line_len;
+
+#if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode)
+ rl_point = 0;
+#endif /* VI_MODE */
+ }
+ return 0;
+}
+
+/* Make C be the next command to be executed. */
+rl_execute_next (c)
+ int c;
+{
+ rl_pending_input = c;
+ return 0;
+}
+
+/* **************************************************************** */
+/* */
+/* The Mark and the Region. */
+/* */
+/* **************************************************************** */
+
+/* Set the mark at POSITION. */
+rl_set_mark (position)
+ int position;
+{
+ if (position > rl_end)
+ return -1;
+
+ rl_mark = position;
+ return 0;
+}
+
+/* Exchange the position of mark and point. */
+rl_exchange_mark_and_point (count, key)
+ int count, key;
+{
+ if (rl_mark > rl_end)
+ rl_mark = -1;
+
+ if (rl_mark == -1)
+ {
+ ding ();
+ return -1;
+ }
+ else
+ {
+ int temp = rl_point;
+
+ rl_point = rl_mark;
+ rl_mark = temp;
+ }
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* 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. */
+int rl_max_kills = DEFAULT_MAX_KILLS;
+
+/* Where to store killed text. */
+char **rl_kill_ring = (char **)NULL;
+
+/* Where we are in the kill ring. */
+int rl_kill_index = 0;
+
+/* How many slots we have in the kill ring. */
+int rl_kill_ring_length = 0;
+
+/* How to say that you only want to save a certain amount
+ of kill material. */
+rl_set_retained_kills (num)
+ int num;
+{
+ 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. */
+rl_kill_text (from, to)
+ int from, to;
+{
+ int slot;
+ char *text;
+
+ /* Is there anything to kill? */
+ if (from == to)
+ {
+ last_command_was_kill++;
+ return 0;
+ }
+
+ text = rl_copy_text (from, to);
+
+ /* Delete the copied text from the line. */
+ rl_delete_text (from, to);
+
+ /* First, find the slot to work with. */
+ if (!last_command_was_kill)
+ {
+ /* Get a new slot. */
+ if (!rl_kill_ring)
+ {
+ /* 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 (last_command_was_kill && rl_editing_mode != vi_mode)
+ {
+ char *old = rl_kill_ring[slot];
+ char *new = xmalloc (1 + strlen (old) + strlen (text));
+
+ if (from < to)
+ {
+ 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;
+ 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. */
+rl_kill_word (count, key)
+ int count, key;
+{
+ int orig_point = rl_point;
+
+ if (count < 0)
+ return (rl_backward_kill_word (-count));
+ else
+ {
+ rl_forward_word (count);
+
+ if (rl_point != orig_point)
+ rl_kill_text (orig_point, rl_point);
+
+ rl_point = orig_point;
+ }
+ return 0;
+}
+
+/* Rubout the word before point, placing it on the kill ring. */
+rl_backward_kill_word (count, ignore)
+ int count, ignore;
+{
+ int orig_point = rl_point;
+
+ if (count < 0)
+ return (rl_kill_word (-count));
+ else
+ {
+ rl_backward_word (count);
+
+ if (rl_point != orig_point)
+ rl_kill_text (orig_point, rl_point);
+ }
+ return 0;
+}
+
+/* Kill from here to the end of the line. If DIRECTION is negative, kill
+ back to the line start instead. */
+rl_kill_line (direction, ignore)
+ int direction, ignore;
+{
+ int orig_point = rl_point;
+
+ if (direction < 0)
+ return (rl_backward_kill_line (1));
+ else
+ {
+ rl_end_of_line (1, ignore);
+ if (orig_point != rl_point)
+ rl_kill_text (orig_point, rl_point);
+ rl_point = orig_point;
+ }
+ return 0;
+}
+
+/* Kill backwards to the start of the line. If DIRECTION is negative, kill
+ forwards to the line end instead. */
+rl_backward_kill_line (direction, ignore)
+ int direction, ignore;
+{
+ int orig_point = rl_point;
+
+ if (direction < 0)
+ return (rl_kill_line (1));
+ else
+ {
+ if (!rl_point)
+ ding ();
+ else
+ {
+ rl_beg_of_line (1, ignore);
+ rl_kill_text (orig_point, rl_point);
+ }
+ }
+ return 0;
+}
+
+/* Kill the whole line, no matter where point is. */
+rl_kill_full_line (count, ignore)
+ int count, ignore;
+{
+ rl_begin_undo_group ();
+ rl_point = 0;
+ rl_kill_text (rl_point, rl_end);
+ rl_end_undo_group ();
+ return 0;
+}
+
+/* Yank back the last killed text. This ignores arguments. */
+rl_yank (count, ignore)
+ int count, ignore;
+{
+ if (!rl_kill_ring)
+ {
+ rl_abort (count, ignore);
+ return -1;
+ }
+
+ rl_set_mark (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. */
+rl_yank_pop (count, key)
+ int count, key;
+{
+ int l;
+
+ if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
+ !rl_kill_ring)
+ {
+ rl_abort (1, key);
+ return -1;
+ }
+
+ l = strlen (rl_kill_ring[rl_kill_index]);
+ if (((rl_point - l) >= 0) &&
+ (strncmp (the_line + (rl_point - l),
+ rl_kill_ring[rl_kill_index], l) == 0))
+ {
+ rl_delete_text ((rl_point - l), rl_point);
+ rl_point -= l;
+ 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 (1, key);
+ return -1;
+ }
+}
+
+/* Yank the COUNTth argument from the previous history line. */
+rl_yank_nth_arg (count, ignore)
+ int count, ignore;
+{
+ register HIST_ENTRY *entry = previous_history ();
+ char *arg;
+
+ if (entry)
+ next_history ();
+ else
+ {
+ ding ();
+ return -1;
+ }
+
+ arg = history_arg_extract (count, count, entry->line);
+ if (!arg || !*arg)
+ {
+ ding ();
+ return -1;
+ }
+
+ rl_begin_undo_group ();
+
+#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 ();
+ rl_insert_text (" ");
+ }
+#endif /* VI_MODE */
+
+ rl_insert_text (arg);
+ free (arg);
+
+ rl_end_undo_group ();
+ return 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;
+{
+ if (rl_explicit_arg)
+ return (rl_yank_nth_arg (count, key));
+ else
+ return (rl_yank_nth_arg ('$', key));
+}
+
+/* How to toggle back and forth between editing modes. */
+rl_vi_editing_mode (count, key)
+ int count, key;
+{
+#if defined (VI_MODE)
+ rl_editing_mode = vi_mode;
+ rl_vi_insertion_mode ();
+ return 0;
+#endif /* VI_MODE */
+}
+
+rl_emacs_editing_mode (count, key)
+ int count, key;
+{
+ rl_editing_mode = emacs_mode;
+ _rl_keymap = emacs_standard_keymap;
+ return 0;
+}
+
+
+/* **************************************************************** */
+/* */
+/* USG (System V) Support */
+/* */
+/* **************************************************************** */
+
+int
+rl_getc (stream)
+ FILE *stream;
+{
+ int result;
+ unsigned char c;
+
+#if defined (__GO32__)
+ if (isatty (0))
+ return (getkey () & 0x7F);
+#endif /* __GO32__ */
+
+ 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 (EWOULDBLOCK)
+ if (errno == EWOULDBLOCK)
+ {
+ int flags;
+
+ if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
+ return (EOF);
+ if (flags & O_NDELAY)
+ {
+ flags &= ~O_NDELAY;
+ fcntl (fileno (stream), F_SETFL, flags);
+ continue;
+ }
+ continue;
+ }
+#endif /* EWOULDBLOCK */
+
+#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK)
+ if (errno == EAGAIN)
+ {
+ int flags;
+
+ if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
+ return (EOF);
+ if (flags & O_NONBLOCK)
+ {
+ flags &= ~O_NONBLOCK;
+ fcntl (fileno (stream), F_SETFL, flags);
+ continue;
+ }
+ }
+#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
+
+#if !defined (__GO32__)
+ /* 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);
+#endif /* !__GO32__ */
+ }
+}
+
+#if !defined (SHELL)
+/* Backwards compatibilty, now that savestring has been removed from
+ all `public' readline header files. */
+char *
+rl_savestring (s)
+ char *s;
+{
+ return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s)));
+}
+#endif
+
+/* Function equivalents for the macros defined in chartypes.h. */
+#undef uppercase_p
+int
+uppercase_p (c)
+ int c;
+{
+ return (isupper (c));
+}
+
+#undef lowercase_p
+int
+lowercase_p (c)
+ int c;
+{
+ return (islower (c));
+}
+
+#undef pure_alphabetic
+int
+pure_alphabetic (c)
+ int c;
+{
+ return (isupper (c) || islower (c));
+}
+
+#undef digit_p
+int
+digit_p (c)
+ int c;
+{
+ return (isdigit (c));
+}
+
+#undef to_lower
+int
+to_lower (c)
+ int c;
+{
+ return (isupper (c) ? tolower (c) : c);
+}
+
+#undef to_upper
+int
+to_upper (c)
+ int c;
+{
+ return (islower (c) ? toupper (c) : c);
+}
+
+#undef digit_value
+int
+digit_value (c)
+ int c;
+{
+ return (isdigit (c) ? c - '0' : c);
+}
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)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 ();
+}
+#endif /* STATIC_MALLOC */
+
+
+/* **************************************************************** */
+/* */
+/* Testing Readline */
+/* */
+/* **************************************************************** */
+
+#if defined (TEST)
+
+main ()
+{
+ HIST_ENTRY **history_list ();
+ char *temp = (char *)NULL;
+ char *prompt = "readline% ";
+ int 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 = history_list ();
+ register int i;
+ if (list)
+ {
+ for (i = 0; list[i]; i++)
+ {
+ fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
+ free (list[i]->line);
+ }
+ free (list);
+ }
+ }
+ free (temp);
+ }
+}
+
+#endif /* TEST */
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -g -traditional -I. -I.. -DTEST -o readline readline.c keymaps.o funmap.o history.o -ltermcap"
+ * end:
+ */
diff --git a/gnu/lib/libreadline/readline.h b/gnu/lib/libreadline/readline.h
new file mode 100644
index 0000000..652d8ca
--- /dev/null
+++ b/gnu/lib/libreadline/readline.h
@@ -0,0 +1,290 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (_READLINE_H_)
+#define _READLINE_H_
+
+#if defined (READLINE_LIBRARY)
+# include "keymaps.h"
+# include "tilde.h"
+#else
+# include <readline/keymaps.h>
+# include <readline/tilde.h>
+#endif
+
+/* The functions for manipulating the text of the line within readline.
+Most of these functions are bound to keys by default. */
+extern int
+ rl_tilde_expand (),
+ rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
+ rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (),
+ rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
+ rl_quoted_insert (), rl_reverse_search_history (), rl_transpose_chars (),
+ rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout (),
+ rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
+ rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
+ rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words (),
+ rl_complete (), rl_possible_completions (), rl_insert_completions (),
+ rl_do_lowercase_version (), rl_kill_full_line (),
+ rl_digit_argument (), rl_universal_argument (), rl_abort (),
+ rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
+ rl_end_of_history (), rl_forward_search_history (), rl_insert (),
+ rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
+ rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (),
+ rl_delete_horizontal_space (), rl_history_search_forward (),
+ rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg ();
+
+/* `Public' utility functions. */
+extern int rl_insert_text (), rl_delete_text (), rl_kill_text ();
+extern int rl_complete_internal ();
+extern int rl_expand_prompt ();
+extern int rl_initialize ();
+extern int rl_set_signals (), rl_clear_signals ();
+extern int rl_init_argument (), rl_digit_argument ();
+extern int rl_read_key (), rl_getc (), rl_stuff_char ();
+extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line ();
+extern int rl_modifying ();
+
+extern int rl_begin_undo_group (), rl_end_undo_group ();
+extern void rl_add_undo (), free_undo_list ();
+extern int rl_do_undo ();
+
+/* Not available unless readline is compiled -DPAREN_MATCHING. */
+extern int rl_insert_close ();
+
+/* These are *both* defined even when VI_MODE is not. */
+extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
+
+/* Non incremental history searching. */
+extern int
+ rl_noninc_forward_search (), rl_noninc_reverse_search (),
+ rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
+
+/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
+extern int rl_vi_check (), rl_vi_textmod_command ();
+extern int
+ rl_vi_redo (), rl_vi_tilde_expand (),
+ rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
+ rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
+ rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
+ rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (),
+ rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (),
+ rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
+ rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (),
+ rl_vi_change_char (), rl_vi_yank_arg (), rl_vi_search (),
+ rl_vi_search_again (), rl_vi_subst (), rl_vi_overstrike (),
+ rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
+ rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (),
+ rl_vi_complete (), rl_vi_fetch_history ();
+
+/* Keyboard macro commands. */
+extern int rl_start_kbd_macro (), rl_end_kbd_macro ();
+extern int rl_call_last_kbd_macro ();
+
+extern int rl_arrow_keys(), rl_refresh_line ();
+
+/* 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 {
+ char *name;
+ Function *function;
+} FUNMAP;
+
+extern FUNMAP **funmap;
+
+/* **************************************************************** */
+/* */
+/* Well Published Variables */
+/* */
+/* **************************************************************** */
+
+/* The name of the calling program. You should initialize this to
+ whatever was in argv[0]. It is used when parsing conditionals. */
+extern char *rl_readline_name;
+
+/* The line buffer that is in use. */
+extern char *rl_line_buffer;
+
+/* The location of point, and end. */
+extern int rl_point, rl_end;
+
+/* The name of the terminal to use. */
+extern char *rl_terminal_name;
+
+/* The input and output streams. */
+extern FILE *rl_instream, *rl_outstream;
+
+/* 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 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 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 char *rl_completer_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 char *rl_special_prefixes;
+
+/* Pointer to the generator function for completion_matches ().
+ NULL means to use filename_entry_function (), the default filename
+ completer. */
+extern Function *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 Function *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 CPPFunction *rl_attempted_completion_function;
+
+/* If non-zero, then this is the address of a function to call just
+ before readline_internal () prints the first prompt. */
+extern Function *rl_startup_hook;
+
+/* 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. */
+extern Function *rl_directory_completion_hook;
+
+/* Backwards compatibility with previous versions of readline. */
+#define rl_symbolic_link_hook rl_directory_completion_hook
+
+/* The address of a function to call periodically while Readline is
+ awaiting character input, or NULL, for no event handling. */
+extern Function *rl_event_hook;
+
+/* Non-zero means that modified history lines are preceded
+ with an asterisk. */
+extern int rl_show_star;
+
+/* 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;
+
+/* Non-zero means to suppress normal filename completion after the
+ user-specified completion function has been called. */
+extern int rl_attempted_completion_over;
+
+/* **************************************************************** */
+/* */
+/* Well Published Functions */
+/* */
+/* **************************************************************** */
+
+/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
+extern char *readline ();
+
+/* These functions are from complete.c. */
+/* Return an array of strings which are the result of repeatadly calling
+ FUNC with TEXT. */
+extern char **completion_matches ();
+extern char *username_completion_function ();
+extern char *filename_completion_function ();
+
+/* These functions are from bind.c. */
+/* rl_add_defun (char *name, Function *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. */
+extern int rl_add_defun ();
+extern int rl_bind_key (), rl_bind_key_in_map ();
+extern int rl_unbind_key (), rl_unbind_key_in_map ();
+extern int rl_set_key ();
+extern int rl_macro_bind (), rl_generic_bind (), rl_variable_bind ();
+extern int rl_translate_keyseq ();
+extern Function *rl_named_function (), *rl_function_of_keyseq ();
+extern int rl_parse_and_bind ();
+extern Keymap rl_get_keymap (), rl_get_keymap_by_name ();
+extern void rl_set_keymap ();
+extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map ();
+extern void rl_function_dumper ();
+extern int rl_read_init_file ();
+
+/* Functions in funmap.c */
+extern void rl_list_funmap_names ();
+extern void rl_initialize_funmap ();
+
+/* Functions in display.c */
+extern void rl_redisplay ();
+extern int rl_message (), rl_clear_message ();
+extern int rl_reset_line_state ();
+extern int rl_character_len ();
+extern int rl_show_char ();
+extern int crlf (), rl_on_new_line ();
+extern int rl_forced_update_display ();
+
+/* Definitions available for use by readline clients. */
+#define RL_PROMPT_START_IGNORE '\001'
+#define RL_PROMPT_END_IGNORE '\002'
+
+#if !defined (savestring)
+#define savestring rl_savestring /* XXX backwards compatibility */
+#endif
+extern char *rl_savestring ();
+
+#endif /* _READLINE_H_ */
diff --git a/gnu/lib/libreadline/rlconf.h b/gnu/lib/libreadline/rlconf.h
new file mode 100644
index 0000000..a9b100f
--- /dev/null
+++ b/gnu/lib/libreadline/rlconf.h
@@ -0,0 +1,57 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, 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
+
+/* If defined, readline shows opening parens and braces when closing
+ paren or brace entered. */
+#define PAREN_MATCHING
+
+/* 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 vi-mode `insert comment' command. */
+#define VI_COMMENT_BEGIN_DEFAULT "#"
+
+#endif /* _RLCONF_H_ */
diff --git a/gnu/lib/libreadline/rldefs.h b/gnu/lib/libreadline/rldefs.h
new file mode 100644
index 0000000..683f8b5
--- /dev/null
+++ b/gnu/lib/libreadline/rldefs.h
@@ -0,0 +1,212 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (_RLDEFS_H)
+#define _RLDEFS_H
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#if !defined (PRAGMA_ALLOCA)
+# include "memalloc.h"
+#endif
+
+#define NEW_TTY_DRIVER
+#define HAVE_BSD_SIGNALS
+/* #define USE_XON_XOFF */
+
+#if defined (__linux__) || defined (HAVE_TERMCAP_H)
+# include <termcap.h>
+#endif /* __linux__ || HAVE_TERMCAP_H */
+
+/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
+#if defined (USG) && !defined (hpux)
+# undef HAVE_BSD_SIGNALS
+#endif
+
+/* System V machines use termio. */
+#if !defined (_POSIX_VERSION)
+# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || \
+ defined (DGUX) || defined (HAVE_TERMIO_H)
+# undef NEW_TTY_DRIVER
+# define TERMIO_TTY_DRIVER
+# include <termio.h>
+# if !defined (TCOON)
+# define TCOON 1
+# endif
+# endif /* USG || hpux || Xenix || sgi || DUGX || HAVE_TERMIO_H */
+#endif /* !_POSIX_VERSION */
+
+/* Posix systems use termios and the Posix signal functions. */
+#if defined (_POSIX_VERSION)
+# if !defined (TERMIOS_MISSING)
+# undef NEW_TTY_DRIVER
+# define TERMIOS_TTY_DRIVER
+# include <termios.h>
+# endif /* !TERMIOS_MISSING */
+# define HAVE_POSIX_SIGNALS
+# if !defined (O_NDELAY)
+# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
+# endif /* O_NDELAY */
+#endif /* _POSIX_VERSION */
+
+/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */
+#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
+# if defined (USGr3) && !defined (XENIX_22)
+# if !defined (HAVE_USG_SIGHOLD)
+# define HAVE_USG_SIGHOLD
+# endif /* !HAVE_USG_SIGHOLD */
+# endif /* USGr3 && !XENIX_22 */
+#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
+
+/* Other (BSD) machines use sgtty. */
+#if defined (NEW_TTY_DRIVER)
+# include <sgtty.h>
+#endif
+
+#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
+# if !defined (HAVE_DIRENT_H)
+# define HAVE_DIRENT_H
+# endif /* !HAVE_DIRENT_H */
+#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
+
+#if defined (HAVE_DIRENT_H)
+# include <dirent.h>
+# define D_NAMLEN(d) strlen ((d)->d_name)
+#else /* !HAVE_DIRENT_H */
+# define D_NAMLEN(d) ((d)->d_namlen)
+# if defined (USG)
+# if defined (Xenix)
+# include <sys/ndir.h>
+# else /* !Xenix (but USG...) */
+# include "ndir.h"
+# endif /* !Xenix */
+# else /* !USG */
+# include <sys/dir.h>
+# endif /* !USG */
+# if !defined (dirent)
+# define dirent direct
+# endif /* !dirent */
+#endif /* !HAVE_DIRENT_H */
+
+#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux)
+# if defined (HAVE_SYS_STREAM_H)
+# include <sys/stream.h>
+# endif /* HAVE_SYS_STREAM_H */
+# if defined (HAVE_SYS_PTEM_H)
+# include <sys/ptem.h>
+# endif /* HAVE_SYS_PTEM_H */
+# if defined (HAVE_SYS_PTE_H)
+# include <sys/pte.h>
+# endif /* HAVE_SYS_PTE_H */
+#endif /* USG && TIOCGWINSZ && !Linux */
+
+/* Posix macro to check file in statbuf for directory-ness.
+ This requires that <sys/stat.h> 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 (USG) || defined (NeXT)
+# if !defined (HAVE_STRING_H)
+# define HAVE_STRING_H
+# endif /* !HAVE_STRING_H */
+#endif /* USG || NeXT */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if !defined (strchr) && !defined (__STDC__)
+extern char *strchr (), *strrchr ();
+#endif /* !strchr && !__STDC__ */
+
+#if defined (HAVE_VARARGS_H)
+# include <varargs.h>
+#endif /* HAVE_VARARGS_H */
+
+/* This is needed to include support for TIOCGWINSZ and window resizing. */
+#if defined (OSF1) || defined (BSD386) || defined (NetBSD) || \
+ defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \
+ defined (AIX)
+# define GWINSZ_IN_SYS_IOCTL
+#endif
+
+/* 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_VDISABLE */
+#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
+
+
+#if !defined (emacs_mode)
+# define no_mode -1
+# define vi_mode 0
+# define emacs_mode 1
+#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) (Function *)((int)(data))
+#else
+# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
+# define KEYMAP_TO_FUNCTION(data) (Function *)(data)
+#endif
+
+#ifndef savestring
+extern char *xmalloc ();
+#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
+#endif
+
+/* Possible values for _rl_bell_preference. */
+#define NO_BELL 0
+#define AUDIBLE_BELL 1
+#define VISIBLE_BELL 2
+
+/* CONFIGURATION SECTION */
+#include "rlconf.h"
+
+#endif /* !_RLDEFS_H */
diff --git a/gnu/lib/libreadline/rltty.c b/gnu/lib/libreadline/rltty.c
new file mode 100644
index 0000000..02c036d
--- /dev/null
+++ b/gnu/lib/libreadline/rltty.c
@@ -0,0 +1,705 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#if defined (HAVE_CONFIG_H)
+# include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include "rldefs.h"
+#include "readline.h"
+
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+extern int readline_echoing_p;
+extern int _rl_eof_char;
+
+#if defined (__GO32__)
+# include <sys/pc.h>
+# undef HANDLE_SIGNALS
+#endif /* __GO32__ */
+
+/* **************************************************************** */
+/* */
+/* 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 = 0;
+
+/* 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)
+ 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;
+}
+
+/* **************************************************************** */
+/* */
+/* Controlling the Meta Key and Keypad */
+/* */
+/* **************************************************************** */
+
+extern int term_has_meta;
+extern char *term_mm;
+extern char *term_mo;
+
+extern char *term_ks;
+extern char *term_ke;
+
+static int
+outchar (c)
+ int c;
+{
+ return putc (c, rl_outstream);
+}
+
+/* Turn on/off the meta key depending on ON. */
+static void
+control_meta_key (on)
+ int on;
+{
+ if (term_has_meta)
+ {
+ if (on && term_mm)
+ tputs (term_mm, 1, outchar);
+ else if (!on && term_mo)
+ tputs (term_mo, 1, outchar);
+ }
+}
+
+#if 0
+static void
+control_keypad (on)
+ int on;
+{
+ if (on && term_ks)
+ tputs (term_ks, 1, outchar);
+ else if (!on && term_ke)
+ tputs (term_ke, 1, outchar);
+}
+#endif
+
+/* **************************************************************** */
+/* */
+/* Saving and Restoring the TTY */
+/* */
+/* **************************************************************** */
+
+/* Non-zero means that the terminal is in a prepped state. */
+static int terminal_prepped = 0;
+
+/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
+ and output is suspended. */
+#if defined (__ksr1__)
+static int ksrflow = 0;
+#endif
+#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 int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+#if !defined (SHELL) && defined (TIOCGWINSZ)
+ struct winsize w;
+
+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+ (void) ioctl (tty, TIOCSWINSZ, &w);
+#endif
+
+ tiop->flags = tiop->lflag = 0;
+
+ ioctl (tty, TIOCGETP, &(tiop->sgttyb));
+ tiop->flags |= SGTTY_SET;
+
+#if defined (TIOCLGET)
+ ioctl (tty, TIOCLGET, &(tiop->lflag));
+ tiop->flags |= LFLAG_SET;
+#endif
+
+#if defined (TIOCGETC)
+ ioctl (tty, TIOCGETC, &(tiop->tchars));
+ tiop->flags |= TCHARS_SET;
+#endif
+
+#if defined (TIOCGLTC)
+ ioctl (tty, TIOCGLTC, &(tiop->ltchars));
+ tiop->flags |= LTCHARS_SET;
+#endif
+
+ return 0;
+}
+
+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, otio, tiop)
+ int meta_flag;
+ TIOTYPE otio, *tiop;
+{
+#if !defined (__GO32__)
+ readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
+
+ /* Copy the original settings to the structure we're going to use for
+ our settings. */
+ tiop->sgttyb = otio.sgttyb;
+ tiop->lflag = otio.lflag;
+#if defined (TIOCGETC)
+ tiop->tchars = otio.tchars;
+#endif
+#if defined (TIOCGLTC)
+ tiop->ltchars = otio.ltchars;
+#endif
+ tiop->flags = otio.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 (((otio.sgttyb.sg_flags & ANYP) == ANYP) ||
+ ((otio.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 (otio.tchars.t_startc != -1)
+ rl_bind_key (otio.tchars.t_startc, rl_restart_output);
+# endif /* USE_XON_XOFF */
+
+ /* If there is an EOF char, bind _rl_eof_char to it. */
+ if (otio.tchars.t_eofc != -1)
+ _rl_eof_char = otio.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 */
+#endif /* !__GO32__ */
+}
+
+#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))
+# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, tiop))
+#else
+# define TIOTYPE struct termio
+# define DRAIN_OUTPUT(fd)
+# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
+# define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop))
+#endif /* !TERMIOS_TTY_DRIVER */
+
+static TIOTYPE otio;
+
+#if defined (FLUSHO)
+# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
+#else
+# define OUTPUT_BEING_FLUSHED(tp) 0
+#endif
+
+static int
+get_tty_settings (tty, tiop)
+ int tty;
+ TIOTYPE *tiop;
+{
+ int ioctl_ret;
+#if !defined (SHELL) && defined (TIOCGWINSZ)
+ struct winsize w;
+
+ if (ioctl (tty, TIOCGWINSZ, &w) == 0)
+ (void) ioctl (tty, TIOCSWINSZ, &w);
+#endif
+
+ /* Keep looping if output is being flushed after a ^O (or whatever
+ the flush character is). */
+ while ((ioctl_ret = GETATTR (tty, tiop)) < 0 || OUTPUT_BEING_FLUSHED (tiop))
+ {
+ if (ioctl_ret < 0 && errno != EINTR)
+ return -1;
+ if (OUTPUT_BEING_FLUSHED (tiop))
+ continue;
+ errno = 0;
+ }
+ 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;
+ }
+
+#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
+
+ return 0;
+}
+
+static void
+prepare_terminal_settings (meta_flag, otio, tiop)
+ int meta_flag;
+ TIOTYPE otio, *tiop;
+{
+ readline_echoing_p = (otio.c_lflag & ECHO);
+
+ tiop->c_lflag &= ~(ICANON | ECHO);
+
+ if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
+ _rl_eof_char = otio.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;
+ otio.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;
+{
+#if !defined (__GO32__)
+ int tty = fileno (rl_instream);
+ TIOTYPE tio;
+
+ if (terminal_prepped)
+ return;
+
+ /* Try to keep this function from being INTerrupted. */
+ block_sigint ();
+
+ if (get_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ otio = tio;
+
+ prepare_terminal_settings (meta_flag, otio, &tio);
+
+ if (set_tty_settings (tty, &tio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ control_meta_key (1);
+#if 0
+ control_keypad (1);
+#endif
+ fflush (rl_outstream);
+ terminal_prepped = 1;
+
+ release_sigint ();
+#endif /* !__GO32__ */
+}
+
+/* Restore the terminal's normal settings and modes. */
+void
+rl_deprep_terminal ()
+{
+#if !defined (__GO32__)
+ int tty = fileno (rl_instream);
+
+ if (!terminal_prepped)
+ return;
+
+ /* Try to keep this function from being INTerrupted. */
+ block_sigint ();
+
+ control_meta_key (0);
+#if 0
+ control_keypad (0);
+#endif
+ fflush (rl_outstream);
+
+ if (set_tty_settings (tty, &otio) < 0)
+ {
+ release_sigint ();
+ return;
+ }
+
+ terminal_prepped = 0;
+
+ release_sigint ();
+#endif /* !__GO32__ */
+}
+
+/* **************************************************************** */
+/* */
+/* Bogus Flow Control */
+/* */
+/* **************************************************************** */
+
+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;
+}
+
+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 */
+/* */
+/* **************************************************************** */
+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[ic].type == ISFUNC) \
+ kmap[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 */
+}
diff --git a/gnu/lib/libreadline/search.c b/gnu/lib/libreadline/search.c
new file mode 100644
index 0000000..d56e554
--- /dev/null
+++ b/gnu/lib/libreadline/search.c
@@ -0,0 +1,370 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include "rldefs.h"
+#include "readline.h"
+#include "history.h"
+
+#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
+#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
+
+#define abs(x) (((x) > 0) ? (x) : -(x))
+
+extern char *xmalloc (), *xrealloc ();
+
+/* Variables imported from readline.c */
+extern int rl_point, rl_end, rl_line_buffer_len;
+extern Keymap _rl_keymap;
+extern int rl_editing_mode;
+extern char *rl_prompt;
+extern char *rl_line_buffer;
+extern HIST_ENTRY *saved_line_for_history;
+extern Function *rl_last_func;
+
+/* Functions imported from the rest of the library. */
+extern int _rl_free_history_entry ();
+
+static char *noninc_search_string = (char *) NULL;
+static int noninc_history_pos = 0;
+static char *prev_line_found = (char *) 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;
+
+ old = where_history ();
+ history_set_pos (pos);
+
+ if (*string == '^')
+ ret = history_search_prefix (string + 1, dir);
+ else
+ ret = history_search (string, dir);
+
+ 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)
+ {
+ ding ();
+ return;
+ }
+
+ pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
+ if (pos == -1)
+ {
+ /* Search failed, current history position unchanged. */
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = 0;
+ 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);
+
+ {
+ int line_len;
+
+ line_len = strlen (entry->line);
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+ strcpy (rl_line_buffer, entry->line);
+ }
+
+ rl_undo_list = (UNDO_LIST *)entry->data;
+ rl_end = strlen (rl_line_buffer);
+ rl_point = 0;
+ rl_clear_message ();
+
+ if (saved_line_for_history)
+ _rl_free_history_entry (saved_line_for_history);
+ saved_line_for_history = (HIST_ENTRY *)NULL;
+}
+
+/* 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, c, pmtlen;
+ char *p;
+
+ maybe_save_line ();
+ saved_point = rl_point;
+
+ /* Use the line buffer to read the search string. */
+ rl_line_buffer[0] = 0;
+ rl_end = rl_point = 0;
+
+ /* XXX - this needs fixing to work with the prompt expansion stuff - XXX */
+ pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
+ p = xmalloc (2 + pmtlen);
+ if (pmtlen)
+ strcpy (p, rl_prompt);
+ p[pmtlen] = pchar ? pchar : ':';
+ p[pmtlen + 1] = '\0';
+
+ rl_message (p, 0, 0);
+ free (p);
+
+ /* Read the search string. */
+ while (c = rl_read_key ())
+ {
+ switch (c)
+ {
+ case CTRL('H'):
+ case RUBOUT:
+ if (rl_point == 0)
+ {
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ return;
+ }
+ rl_rubout (1);
+ 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'):
+ maybe_unsave_line ();
+ rl_clear_message ();
+ rl_point = saved_point;
+ ding ();
+ return;
+
+ default:
+ rl_insert (1, c);
+ break;
+ }
+ rl_redisplay ();
+ }
+
+ dosearch:
+ /* 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)
+ {
+ ding ();
+ return;
+ }
+ }
+ else
+ {
+ /* We want to start the search from the current history position. */
+ noninc_history_pos = where_history ();
+ if (noninc_search_string)
+ free (noninc_search_string);
+ noninc_search_string = savestring (rl_line_buffer);
+ }
+
+ noninc_dosearch (noninc_search_string, dir);
+}
+
+/* Search forward through the history list for a string. If the vi-mode
+ code calls this, KEY will be `?'. */
+rl_noninc_forward_search (count, key)
+ int count, key;
+{
+ if (key == '?')
+ noninc_search (1, '?');
+ else
+ noninc_search (1, 0);
+ return 0;
+}
+
+/* Reverse search the history list for a string. If the vi-mode code
+ calls this, KEY will be `/'. */
+rl_noninc_reverse_search (count, key)
+ int count, key;
+{
+ if (key == '/')
+ noninc_search (-1, '/');
+ else
+ noninc_search (-1, 0);
+ return 0;
+}
+
+/* Search forward through the history list for the last string searched
+ for. If there is no saved search string, abort. */
+rl_noninc_forward_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ 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. */
+rl_noninc_reverse_search_again (count, key)
+ int count, key;
+{
+ if (!noninc_search_string)
+ {
+ ding ();
+ return (-1);
+ }
+ noninc_dosearch (noninc_search_string, -1);
+ return 0;
+}
+
+static int
+rl_history_search_internal (count, direction)
+ int count, direction;
+{
+ HIST_ENTRY *temp, *old_temp;
+ int line_len;
+
+ maybe_save_line ();
+
+ temp = old_temp = (HIST_ENTRY *)NULL;
+ while (count)
+ {
+ temp = (direction < 0) ? previous_history () : next_history ();
+ if (!temp)
+ break;
+ if (STREQN (rl_line_buffer, temp->line, rl_point))
+ {
+ /* Don't find multiple instances of the same line. */
+ if (prev_line_found && STREQ (prev_line_found, temp->line))
+ continue;
+ if (direction < 0)
+ old_temp = temp;
+ prev_line_found = temp->line;
+ count--;
+ }
+ }
+
+ if (!temp)
+ {
+ if (direction < 0 && old_temp)
+ temp = old_temp;
+ else
+ {
+ maybe_unsave_line ();
+ ding ();
+ return 1;
+ }
+ }
+
+ line_len = strlen (temp->line);
+ if (line_len >= rl_line_buffer_len)
+ rl_extend_line_buffer (line_len);
+ strcpy (rl_line_buffer, temp->line);
+ rl_undo_list = (UNDO_LIST *)temp->data;
+ rl_end = line_len;
+ return 0;
+}
+
+/* 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)
+ prev_line_found = (char *)NULL;
+ 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_backward)
+ prev_line_found = (char *)NULL;
+ return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
+}
diff --git a/gnu/lib/libreadline/signals.c b/gnu/lib/libreadline/signals.c
new file mode 100644
index 0000000..e3d93a0
--- /dev/null
+++ b/gnu/lib/libreadline/signals.c
@@ -0,0 +1,287 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if !defined (NO_SYS_FILE)
+# include <sys/file.h>
+#endif /* !NO_SYS_FILE */
+#include <signal.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include <errno.h>
+/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
+#if !defined (errno)
+extern int errno;
+#endif /* !errno */
+
+#include "posixstat.h"
+
+/* System-specific feature definitions and include files. */
+#include "rldefs.h"
+
+#if defined (GWINSZ_IN_SYS_IOCTL)
+# include <sys/ioctl.h>
+#endif /* GWINSZ_IN_SYS_IOCTL */
+
+/* Some standard library routines. */
+#include "readline.h"
+#include "history.h"
+
+extern int readline_echoing_p;
+extern int rl_pending_input;
+extern int _rl_meta_flag;
+
+extern void free_undo_list ();
+
+#if defined (VOID_SIGHANDLER)
+# define sighandler void
+#else
+# define sighandler int
+#endif /* VOID_SIGHANDLER */
+
+/* This typedef is equivalant to the one for Function; it allows us
+ to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
+typedef sighandler SigHandler ();
+
+#if defined (__GO32__)
+# undef HANDLE_SIGNALS
+#endif /* __GO32__ */
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+
+/* **************************************************************** */
+/* */
+/* Signal Handling */
+/* */
+/* **************************************************************** */
+
+#if defined (SIGWINCH)
+static SigHandler *old_sigwinch = (SigHandler *)NULL;
+
+static sighandler
+rl_handle_sigwinch (sig)
+ int sig;
+{
+ if (readline_echoing_p)
+ {
+ _rl_set_screen_size (fileno (rl_instream), 1);
+ _rl_redisplay_after_sigwinch ();
+ }
+
+ if (old_sigwinch &&
+ old_sigwinch != (SigHandler *)SIG_IGN &&
+ old_sigwinch != (SigHandler *)SIG_DFL)
+ (*old_sigwinch) (sig);
+#if !defined (VOID_SIGHANDLER)
+ return (0);
+#endif /* VOID_SIGHANDLER */
+}
+#endif /* SIGWINCH */
+
+#if defined (HANDLE_SIGNALS)
+/* Interrupt handling. */
+static SigHandler
+ *old_int = (SigHandler *)NULL,
+ *old_alrm = (SigHandler *)NULL;
+#if !defined (SHELL)
+static SigHandler
+ *old_tstp = (SigHandler *)NULL,
+ *old_ttou = (SigHandler *)NULL,
+ *old_ttin = (SigHandler *)NULL,
+ *old_cont = (SigHandler *)NULL;
+#endif /* !SHELL */
+
+/* Handle an interrupt character. */
+static sighandler
+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;
+# endif /* HAVE_BSD_SIGNALS */
+#endif /* !HAVE_POSIX_SIGNALS */
+
+#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)
+ signal (sig, SIG_IGN);
+#endif /* !HAVE_BSD_SIGNALS */
+
+ switch (sig)
+ {
+ case SIGINT:
+ {
+ register HIST_ENTRY *entry;
+
+ free_undo_list ();
+
+ entry = current_history ();
+ if (entry)
+ entry->data = (char *)NULL;
+ }
+ _rl_kill_kbd_macro ();
+ rl_clear_message ();
+ rl_init_argument ();
+
+#if defined (SIGTSTP)
+ case SIGTSTP:
+ case SIGTTOU:
+ case SIGTTIN:
+#endif /* SIGTSTP */
+ case SIGALRM:
+ rl_clean_up_for_exit ();
+ rl_deprep_terminal ();
+ rl_clear_signals ();
+ rl_pending_input = 0;
+
+#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 */
+
+ 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_prep_terminal (_rl_meta_flag);
+ rl_set_signals ();
+ }
+
+#if !defined (VOID_SIGHANDLER)
+ return (0);
+#endif /* !VOID_SIGHANDLER */
+}
+
+#if defined (HAVE_POSIX_SIGNALS)
+static SigHandler *
+rl_set_sighandler (sig, handler)
+ int sig;
+ SigHandler *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 /* !HAVE_POSIX_SIGNALS */
+# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
+#endif /* !HAVE_POSIX_SIGNALS */
+
+rl_set_signals ()
+{
+ old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
+ if (old_int == (SigHandler *)SIG_IGN)
+ rl_set_sighandler (SIGINT, SIG_IGN);
+
+ old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
+ if (old_alrm == (SigHandler *)SIG_IGN)
+ rl_set_sighandler (SIGALRM, SIG_IGN);
+
+#if !defined (SHELL)
+
+#if defined (SIGTSTP)
+ old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
+ if (old_tstp == (SigHandler *)SIG_IGN)
+ rl_set_sighandler (SIGTSTP, SIG_IGN);
+#endif /* SIGTSTP */
+#if defined (SIGTTOU)
+ old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
+ old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
+
+ if (old_tstp == (SigHandler *)SIG_IGN)
+ {
+ rl_set_sighandler (SIGTTOU, SIG_IGN);
+ rl_set_sighandler (SIGTTIN, SIG_IGN);
+ }
+#endif /* SIGTTOU */
+
+#endif /* !SHELL */
+
+#if defined (SIGWINCH)
+ old_sigwinch =
+ (SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
+#endif /* SIGWINCH */
+ return 0;
+}
+
+rl_clear_signals ()
+{
+ rl_set_sighandler (SIGINT, old_int);
+ rl_set_sighandler (SIGALRM, old_alrm);
+
+#if !defined (SHELL)
+
+#if defined (SIGTSTP)
+ rl_set_sighandler (SIGTSTP, old_tstp);
+#endif
+
+#if defined (SIGTTOU)
+ rl_set_sighandler (SIGTTOU, old_ttou);
+ rl_set_sighandler (SIGTTIN, old_ttin);
+#endif /* SIGTTOU */
+
+#endif /* !SHELL */
+
+#if defined (SIGWINCH)
+ rl_set_sighandler (SIGWINCH, old_sigwinch);
+#endif
+
+ return 0;
+}
+#endif /* HANDLE_SIGNALS */
diff --git a/gnu/lib/libreadline/tilde.c b/gnu/lib/libreadline/tilde.c
new file mode 100644
index 0000000..736f1e6
--- /dev/null
+++ b/gnu/lib/libreadline/tilde.c
@@ -0,0 +1,380 @@
+/* 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined (HAVE_STRING_H)
+# include <string.h>
+#else /* !HAVE_STRING_H */
+# include <strings.h>
+#endif /* !HAVE_STRING_H */
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#include "tilde.h"
+#include <sys/types.h>
+#include <pwd.h>
+
+#if defined (USG) && !defined (HAVE_GETPW_DECLS)
+extern struct passwd *getpwuid (), *getpwnam ();
+#endif /* USG && !defined (HAVE_GETPW_DECLS) */
+
+#if !defined (savestring)
+extern char *xmalloc ();
+# ifndef strcpy
+extern char *strcpy ();
+# endif
+#define savestring(x) strcpy (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 defined (TEST) || defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* TEST || STATIC_MALLOC */
+
+/* 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 char *default_prefixes[] =
+ { " ~", "\t~", (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 char *default_suffixes[] =
+ { " ", "\n", (char *)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. */
+CPFunction *tilde_expansion_failure_hook = (CPFunction *)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 = 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 = default_suffixes;
+
+/* 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)
+ char *string;
+ int *len;
+{
+ register int i, j, string_len;
+ register char **prefixes = tilde_additional_prefixes;
+
+ string_len = strlen (string);
+ *len = 0;
+
+ if (!*string || *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)
+ char *string;
+{
+ register int i, j, string_len;
+ register char **suffixes = tilde_additional_suffixes;
+
+ string_len = strlen (string);
+
+ for (i = 0; i < string_len; i++)
+ {
+ if (string[i] == '/' || !string[i])
+ 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)
+ char *string;
+{
+ char *result, *tilde_expand_word ();
+ int result_size, result_index;
+
+ result_size = result_index = 0;
+ result = (char *)NULL;
+
+ /* 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);
+ 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);
+}
+
+/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
+ tilde. If there is no expansion, call tilde_expansion_failure_hook. */
+char *
+tilde_expand_word (filename)
+ char *filename;
+{
+ char *dirname;
+
+ dirname = filename ? savestring (filename) : (char *)NULL;
+
+ if (dirname && *dirname == '~')
+ {
+ char *temp_name;
+ if (!dirname[1] || dirname[1] == '/')
+ {
+ /* Prepend $HOME to the rest of the string. */
+ char *temp_home = (char *)getenv ("HOME");
+
+ /* If there is no HOME variable, look up the directory in
+ the password database. */
+ if (!temp_home)
+ {
+ struct passwd *entry;
+
+ entry = getpwuid (getuid ());
+ if (entry)
+ temp_home = entry->pw_dir;
+ }
+
+ temp_name = xmalloc (1 + strlen (&dirname[1])
+ + (temp_home ? strlen (temp_home) : 0));
+ temp_name[0] = '\0';
+ if (temp_home)
+ strcpy (temp_name, temp_home);
+ strcat (temp_name, dirname + 1);
+ free (dirname);
+ dirname = temp_name;
+ }
+ else
+ {
+ char *username;
+ struct passwd *user_entry;
+ int i;
+
+ username = xmalloc (strlen (dirname));
+ for (i = 1; dirname[i] && dirname[i] != '/'; i++)
+ username[i - 1] = dirname[i];
+ username[i - 1] = '\0';
+
+ if ((user_entry = getpwnam (username)) == 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)
+ {
+ char *expansion;
+
+ expansion = (*tilde_expansion_failure_hook) (username);
+
+ if (expansion)
+ {
+ temp_name = xmalloc (1 + strlen (expansion)
+ + strlen (&dirname[i]));
+ strcpy (temp_name, expansion);
+ strcat (temp_name, &dirname[i]);
+ free (expansion);
+ free (dirname);
+ dirname = temp_name;
+ }
+ }
+ /* We shouldn't report errors. */
+ }
+ else
+ {
+ temp_name = xmalloc (1 + strlen (user_entry->pw_dir)
+ + strlen (&dirname[i]));
+ strcpy (temp_name, user_entry->pw_dir);
+ strcat (temp_name, &dirname[i]);
+ free (dirname);
+ dirname = temp_name;
+ }
+ endpwent ();
+ free (username);
+ }
+ }
+ return (dirname);
+}
+
+
+#if defined (TEST)
+#undef NULL
+#include <stdio.h>
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ char *result, line[512];
+ int done = 0;
+
+ while (!done)
+ {
+ printf ("~expand: ");
+ fflush (stdout);
+
+ if (!fgets(line, 512, stdin))
+ 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 char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)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/gnu/lib/libreadline/tilde.h b/gnu/lib/libreadline/tilde.h
new file mode 100644
index 0000000..726d081
--- /dev/null
+++ b/gnu/lib/libreadline/tilde.h
@@ -0,0 +1,38 @@
+/* tilde.h: Externally available variables and function in libtilde.a. */
+
+#if !defined (__TILDE_H__)
+# define __TILDE_H__
+
+/* Function pointers can be declared as (Function *)foo. */
+#if !defined (__FUNCTION_DEF)
+# define __FUNCTION_DEF
+typedef int Function ();
+typedef void VFunction ();
+typedef char *CPFunction ();
+typedef char **CPPFunction ();
+#endif /* _FUNCTION_DEF */
+
+/* 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 CPFunction *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 ();
+
+/* 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 ();
+
+#endif /* __TILDE_H__ */
diff --git a/gnu/lib/libreadline/vi_keymap.c b/gnu/lib/libreadline/vi_keymap.c
new file mode 100644
index 0000000..b8b3123
--- /dev/null
+++ b/gnu/lib/libreadline/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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if !defined (BUFSIZ)
+#include <stdio.h>
+#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, (Function *)0x0 }, /* Control-@ */
+ { ISFUNC, (Function *)0x0 }, /* Control-a */
+ { ISFUNC, (Function *)0x0 }, /* Control-b */
+ { ISFUNC, (Function *)0x0 }, /* Control-c */
+ { ISFUNC, rl_vi_eof_maybe }, /* Control-d */
+ { ISFUNC, rl_emacs_editing_mode }, /* Control-e */
+ { ISFUNC, (Function *)0x0 }, /* Control-f */
+ { ISFUNC, rl_abort }, /* Control-g */
+ { ISFUNC, rl_backward }, /* Control-h */
+ { ISFUNC, (Function *)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, (Function *)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, (Function *)0x0 }, /* Control-x */
+ { ISFUNC, rl_yank }, /* Control-y */
+ { ISFUNC, (Function *)0x0 }, /* Control-z */
+
+ { ISFUNC, (Function *)0x0 }, /* Control-[ */ /* vi_escape_keymap */
+ { ISFUNC, (Function *)0x0 }, /* Control-\ */
+ { ISFUNC, (Function *)0x0 }, /* Control-] */
+ { ISFUNC, (Function *)0x0 }, /* Control-^ */
+ { ISFUNC, rl_undo_command }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, rl_forward }, /* SPACE */
+ { ISFUNC, (Function *)0x0 }, /* ! */
+ { ISFUNC, (Function *)0x0 }, /* " */
+ { ISFUNC, rl_vi_comment }, /* # */
+ { ISFUNC, rl_end_of_line }, /* $ */
+ { ISFUNC, rl_vi_match }, /* % */
+ { ISFUNC, rl_vi_tilde_expand }, /* & */
+ { ISFUNC, (Function *)0x0 }, /* ' */
+ { ISFUNC, (Function *)0x0 }, /* ( */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* : */
+ { ISFUNC, rl_vi_char_search }, /* ; */
+ { ISFUNC, (Function *)0x0 }, /* < */
+ { ISFUNC, rl_vi_complete }, /* = */
+ { ISFUNC, (Function *)0x0 }, /* > */
+ { ISFUNC, rl_vi_search }, /* ? */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* H */
+ { ISFUNC, rl_vi_insert_beg }, /* I */
+ { ISFUNC, (Function *)0x0 }, /* J */
+ { ISFUNC, (Function *)0x0 }, /* K */
+ { ISFUNC, (Function *)0x0 }, /* L */
+ { ISFUNC, (Function *)0x0 }, /* M */
+ { ISFUNC, rl_vi_search_again }, /* N */
+ { ISFUNC, (Function *)0x0 }, /* O */
+ { ISFUNC, rl_vi_put }, /* P */
+ { ISFUNC, (Function *)0x0 }, /* Q */
+ { ISFUNC, rl_vi_replace }, /* R */
+ { ISFUNC, rl_vi_subst }, /* S */
+ { ISFUNC, rl_vi_char_search }, /* T */
+ { ISFUNC, rl_revert_line }, /* U */
+ { ISFUNC, (Function *)0x0 }, /* V */
+ { ISFUNC, rl_vi_next_word }, /* W */
+ { ISFUNC, rl_rubout }, /* X */
+ { ISFUNC, rl_vi_yank_to }, /* Y */
+ { ISFUNC, (Function *)0x0 }, /* Z */
+
+ /* Some more punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* [ */
+ { ISFUNC, rl_vi_complete }, /* \ */
+ { ISFUNC, (Function *)0x0 }, /* ] */
+ { ISFUNC, rl_vi_first_print }, /* ^ */
+ { ISFUNC, rl_vi_yank_arg }, /* _ */
+ { ISFUNC, (Function *)0x0 }, /* ` */
+
+ /* 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, (Function *)0x0 }, /* g */
+ { ISFUNC, rl_backward }, /* h */
+ { ISFUNC, rl_vi_insertion_mode }, /* i */
+ { ISFUNC, rl_get_next_history }, /* j */
+ { ISFUNC, rl_get_previous_history }, /* k */
+ { ISFUNC, rl_forward }, /* l */
+ { ISFUNC, (Function *)0x0 }, /* m */
+ { ISFUNC, rl_vi_search_again }, /* n */
+ { ISFUNC, (Function *)0x0 }, /* o */
+ { ISFUNC, rl_vi_put }, /* p */
+ { ISFUNC, (Function *)0x0 }, /* q */
+ { ISFUNC, rl_vi_change_char }, /* r */
+ { ISFUNC, rl_vi_subst }, /* s */
+ { ISFUNC, rl_vi_char_search }, /* t */
+ { ISFUNC, rl_undo_command }, /* u */
+ { ISFUNC, (Function *)0x0 }, /* v */
+ { ISFUNC, rl_vi_next_word }, /* w */
+ { ISFUNC, rl_vi_delete }, /* x */
+ { ISFUNC, rl_vi_yank_to }, /* y */
+ { ISFUNC, (Function *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* { */
+ { ISFUNC, rl_vi_column }, /* | */
+ { ISFUNC, (Function *)0x0 }, /* } */
+ { ISFUNC, rl_vi_change_case }, /* ~ */
+ { ISFUNC, (Function *)0x0 }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+
+
+KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
+ /* The regular control keys come first. */
+ { ISFUNC, (Function *)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_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 */
+};
+
+/* Unused for the time being. */
+#if 0
+KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
+ /* The regular control keys come first. */
+ { ISFUNC, (Function *)0x0 }, /* Control-@ */
+ { ISFUNC, (Function *)0x0 }, /* Control-a */
+ { ISFUNC, (Function *)0x0 }, /* Control-b */
+ { ISFUNC, (Function *)0x0 }, /* Control-c */
+ { ISFUNC, (Function *)0x0 }, /* Control-d */
+ { ISFUNC, (Function *)0x0 }, /* Control-e */
+ { ISFUNC, (Function *)0x0 }, /* Control-f */
+ { ISFUNC, (Function *)0x0 }, /* Control-g */
+ { ISFUNC, (Function *)0x0 }, /* Control-h */
+ { ISFUNC, rl_tab_insert}, /* Control-i */
+ { ISFUNC, rl_emacs_editing_mode}, /* Control-j */
+ { ISFUNC, rl_kill_line }, /* Control-k */
+ { ISFUNC, (Function *)0x0 }, /* Control-l */
+ { ISFUNC, rl_emacs_editing_mode}, /* Control-m */
+ { ISFUNC, (Function *)0x0 }, /* Control-n */
+ { ISFUNC, (Function *)0x0 }, /* Control-o */
+ { ISFUNC, (Function *)0x0 }, /* Control-p */
+ { ISFUNC, (Function *)0x0 }, /* Control-q */
+ { ISFUNC, (Function *)0x0 }, /* Control-r */
+ { ISFUNC, (Function *)0x0 }, /* Control-s */
+ { ISFUNC, (Function *)0x0 }, /* Control-t */
+ { ISFUNC, (Function *)0x0 }, /* Control-u */
+ { ISFUNC, (Function *)0x0 }, /* Control-v */
+ { ISFUNC, (Function *)0x0 }, /* Control-w */
+ { ISFUNC, (Function *)0x0 }, /* Control-x */
+ { ISFUNC, (Function *)0x0 }, /* Control-y */
+ { ISFUNC, (Function *)0x0 }, /* Control-z */
+
+ { ISFUNC, rl_vi_movement_mode }, /* Control-[ */
+ { ISFUNC, (Function *)0x0 }, /* Control-\ */
+ { ISFUNC, (Function *)0x0 }, /* Control-] */
+ { ISFUNC, (Function *)0x0 }, /* Control-^ */
+ { ISFUNC, rl_undo_command }, /* Control-_ */
+
+ /* The start of printing characters. */
+ { ISFUNC, (Function *)0x0 }, /* SPACE */
+ { ISFUNC, (Function *)0x0 }, /* ! */
+ { ISFUNC, (Function *)0x0 }, /* " */
+ { ISFUNC, (Function *)0x0 }, /* # */
+ { ISFUNC, (Function *)0x0 }, /* $ */
+ { ISFUNC, (Function *)0x0 }, /* % */
+ { ISFUNC, (Function *)0x0 }, /* & */
+ { ISFUNC, (Function *)0x0 }, /* ' */
+ { ISFUNC, (Function *)0x0 }, /* ( */
+ { ISFUNC, (Function *)0x0 }, /* ) */
+ { ISFUNC, (Function *)0x0 }, /* * */
+ { ISFUNC, (Function *)0x0 }, /* + */
+ { ISFUNC, (Function *)0x0 }, /* , */
+ { ISFUNC, (Function *)0x0 }, /* - */
+ { ISFUNC, (Function *)0x0 }, /* . */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* : */
+ { ISFUNC, (Function *)0x0 }, /* ; */
+ { ISFUNC, (Function *)0x0 }, /* < */
+ { ISFUNC, (Function *)0x0 }, /* = */
+ { ISFUNC, (Function *)0x0 }, /* > */
+ { ISFUNC, (Function *)0x0 }, /* ? */
+ { ISFUNC, (Function *)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, (Function *)0x0 }, /* \ */
+ { ISFUNC, (Function *)0x0 }, /* ] */
+ { ISFUNC, (Function *)0x0 }, /* ^ */
+ { ISFUNC, (Function *)0x0 }, /* _ */
+ { ISFUNC, (Function *)0x0 }, /* ` */
+
+ /* Lowercase alphabet. */
+ { ISFUNC, (Function *)0x0 }, /* a */
+ { ISFUNC, (Function *)0x0 }, /* b */
+ { ISFUNC, (Function *)0x0 }, /* c */
+ { ISFUNC, (Function *)0x0 }, /* d */
+ { ISFUNC, (Function *)0x0 }, /* e */
+ { ISFUNC, (Function *)0x0 }, /* f */
+ { ISFUNC, (Function *)0x0 }, /* g */
+ { ISFUNC, (Function *)0x0 }, /* h */
+ { ISFUNC, (Function *)0x0 }, /* i */
+ { ISFUNC, (Function *)0x0 }, /* j */
+ { ISFUNC, (Function *)0x0 }, /* k */
+ { ISFUNC, (Function *)0x0 }, /* l */
+ { ISFUNC, (Function *)0x0 }, /* m */
+ { ISFUNC, (Function *)0x0 }, /* n */
+ { ISFUNC, rl_arrow_keys }, /* o */
+ { ISFUNC, (Function *)0x0 }, /* p */
+ { ISFUNC, (Function *)0x0 }, /* q */
+ { ISFUNC, (Function *)0x0 }, /* r */
+ { ISFUNC, (Function *)0x0 }, /* s */
+ { ISFUNC, (Function *)0x0 }, /* t */
+ { ISFUNC, (Function *)0x0 }, /* u */
+ { ISFUNC, (Function *)0x0 }, /* v */
+ { ISFUNC, (Function *)0x0 }, /* w */
+ { ISFUNC, (Function *)0x0 }, /* x */
+ { ISFUNC, (Function *)0x0 }, /* y */
+ { ISFUNC, (Function *)0x0 }, /* z */
+
+ /* Final punctuation. */
+ { ISFUNC, (Function *)0x0 }, /* { */
+ { ISFUNC, (Function *)0x0 }, /* | */
+ { ISFUNC, (Function *)0x0 }, /* } */
+ { ISFUNC, (Function *)0x0 }, /* ~ */
+ { ISFUNC, rl_backward_kill_word }, /* RUBOUT */
+
+#if KEYMAP_SIZE > 128
+ /* Undefined keys. */
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 },
+ { ISFUNC, (Function *)0x0 }
+#endif /* KEYMAP_SIZE > 128 */
+};
+#endif
diff --git a/gnu/lib/libreadline/vi_mode.c b/gnu/lib/libreadline/vi_mode.c
new file mode 100644
index 0000000..d0b9310
--- /dev/null
+++ b/gnu/lib/libreadline/vi_mode.c
@@ -0,0 +1,1329 @@
+/* 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 1, 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,
+ 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define READLINE_LIBRARY
+
+/* **************************************************************** */
+/* */
+/* VI Emulation Mode */
+/* */
+/* **************************************************************** */
+#include "rlconf.h"
+
+#if defined (VI_MODE)
+
+#include <sys/types.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+/* Some standard library routines. */
+#include "rldefs.h"
+#include "readline.h"
+#include "history.h"
+
+#ifndef digit_p
+#define digit_p(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#ifndef digit_value
+#define digit_value(c) ((c) - '0')
+#endif
+
+#ifndef member
+#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
+#endif
+
+#ifndef isident
+#define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_'))
+#endif
+
+#ifndef exchange
+#define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
+#endif
+
+#ifndef VI_COMMENT_BEGIN_DEFAULT
+#define VI_COMMENT_BEGIN_DEFAULT "#"
+#endif
+
+#if defined (STATIC_MALLOC)
+static char *xmalloc (), *xrealloc ();
+#else
+extern char *xmalloc (), *xrealloc ();
+#endif /* STATIC_MALLOC */
+
+/* Variables imported from readline.c */
+extern int rl_point, rl_end, rl_mark, rl_done;
+extern FILE *rl_instream;
+extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
+extern Keymap _rl_keymap;
+extern char *rl_prompt;
+extern char *rl_line_buffer;
+extern int rl_arg_sign;
+
+extern void _rl_dispatch ();
+
+extern void rl_extend_line_buffer ();
+extern int rl_vi_check ();
+
+/* Non-zero means enter insertion mode. */
+static int _rl_vi_doing_insert = 0;
+
+/* String inserted into the line by rl_vi_comment (). */
+char *rl_vi_comment_begin = (char *)NULL;
+
+/* *** UNCLEAN *** */
+/* Command keys which do movement for xxx_to commands. */
+static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
+
+/* Keymap used for vi replace characters. Created dynamically since
+ rarely used. */
+static Keymap vi_replace_map = (Keymap)NULL;
+
+/* The number of characters inserted in the last replace operation. */
+static int vi_replace_count = 0;
+
+/* 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 = 0;
+
+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 = 0;
+static int _rl_vi_last_search_char = 0;
+static int _rl_vi_last_replacement = 0;
+
+static int vi_redoing = 0;
+
+/* Text modification commands. These are the `redoable' commands. */
+static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
+
+static int rl_digit_loop1 ();
+
+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));
+}
+
+/* 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. */
+rl_vi_redo (count, c)
+ int count, c;
+{
+ if (!rl_explicit_arg)
+ {
+ rl_numeric_arg = _rl_vi_last_repeat;
+ rl_arg_sign = _rl_vi_last_arg_sign;
+ }
+
+ vi_redoing = 1;
+ _rl_dispatch (_rl_vi_last_command, _rl_keymap);
+ vi_redoing = 0;
+
+ return (0);
+}
+
+/* Yank the nth arg from the previous line into this line at point. */
+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. */
+rl_vi_fetch_history (count, c)
+ int count, c;
+{
+ int current = where_history ();
+
+ /* 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)
+ {
+ int wanted = history_base + current - count;
+ if (wanted <= 0)
+ rl_beginning_of_history (0, 0);
+ else
+ rl_get_previous_history (wanted);
+ }
+ else
+ rl_beginning_of_history (count, 0);
+ return (0);
+}
+
+/* Search again for the last thing searched for. */
+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. */
+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:
+ ding ();
+ break;
+ }
+ return (0);
+}
+
+/* Completion, from vi's point of view. */
+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. */
+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. */
+rl_vi_prev_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ return (rl_vi_next_word (-count, key));
+
+ if (rl_point == 0)
+ {
+ ding ();
+ return (0);
+ }
+
+ if (uppercase_p (key))
+ rl_vi_bWord (count);
+ else
+ rl_vi_bword (count);
+
+ return (0);
+}
+
+/* Next word in vi mode. */
+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))
+ {
+ ding ();
+ return (0);
+ }
+
+ if (uppercase_p (key))
+ rl_vi_fWord (count);
+ else
+ rl_vi_fword (count);
+ return (0);
+}
+
+/* Move to the end of the ?next? word. */
+rl_vi_end_word (count, key)
+ int count, key;
+{
+ if (count < 0)
+ {
+ ding ();
+ return -1;
+ }
+
+ if (uppercase_p (key))
+ rl_vi_eWord (count);
+ else
+ rl_vi_eword (count);
+ return (0);
+}
+
+/* Move forward a word the way that 'W' does. */
+rl_vi_fWord (count)
+ int count;
+{
+ 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);
+}
+
+rl_vi_bWord (count)
+ int count;
+{
+ 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);
+}
+
+rl_vi_eWord (count)
+ int count;
+{
+ 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);
+}
+
+rl_vi_fword (count)
+ int count;
+{
+ while (count-- && rl_point < (rl_end - 1))
+ {
+ /* Move to white space (really non-identifer). */
+ if (isident (rl_line_buffer[rl_point]))
+ {
+ while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
+ rl_point++;
+ }
+ else /* if (!whitespace (rl_line_buffer[rl_point])) */
+ {
+ while (!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);
+}
+
+rl_vi_bword (count)
+ int count;
+{
+ 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 = isident (rl_line_buffer[rl_point - 1]);
+ if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
+ (!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 (isident (rl_line_buffer[rl_point]))
+ while (--rl_point >= 0 && isident (rl_line_buffer[rl_point]));
+ else
+ while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) &&
+ !whitespace (rl_line_buffer[rl_point]));
+ rl_point++;
+ }
+ }
+ return (0);
+}
+
+rl_vi_eword (count)
+ int count;
+{
+ 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 (isident (rl_line_buffer[rl_point]))
+ while (++rl_point < rl_end && isident (rl_line_buffer[rl_point]));
+ else
+ while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point])
+ && !whitespace (rl_line_buffer[rl_point]));
+ }
+ rl_point--;
+ }
+ return (0);
+}
+
+rl_vi_insert_beg (count, key)
+ int count, key;
+{
+ rl_beg_of_line (1, key);
+ rl_vi_insertion_mode (1, key);
+ return (0);
+}
+
+rl_vi_append_mode (count, key)
+ int count, key;
+{
+ if (rl_point < rl_end)
+ rl_point++;
+ rl_vi_insertion_mode (1, key);
+ return (0);
+}
+
+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. */
+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. */
+rl_vi_insertion_mode (count, key)
+ int count, key;
+{
+ _rl_keymap = vi_insertion_keymap;
+ return (0);
+}
+
+void
+_rl_vi_done_inserting ()
+{
+ if (_rl_vi_doing_insert)
+ {
+ 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. */
+ _rl_vi_doing_insert = 0;
+ vi_continued_command = 1;
+ }
+ else
+ vi_continued_command = 0;
+}
+
+rl_vi_movement_mode (count, key)
+ int count, key;
+{
+ if (rl_point > 0)
+ rl_backward (1);
+
+#if 0
+ _rl_vi_reset_last ();
+#endif
+
+ _rl_keymap = vi_movement_keymap;
+ _rl_vi_done_inserting ();
+ return (0);
+}
+
+rl_vi_arg_digit (count, c)
+ int count, c;
+{
+ if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
+ return (rl_beg_of_line ());
+ else
+ return (rl_digit_argument (count, c));
+}
+
+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);
+
+ while (count-- && rl_point < rl_end)
+ {
+ if (uppercase_p (rl_line_buffer[rl_point]))
+ c = to_lower (rl_line_buffer[rl_point]);
+ else if (lowercase_p (rl_line_buffer[rl_point]))
+ c = to_upper (rl_line_buffer[rl_point]);
+ else
+ {
+ /* Just skip over characters neither upper nor lower case. */
+ rl_forward (1);
+ continue;
+ }
+
+ /* Vi is kind of strange here. */
+ if (c)
+ {
+ rl_begin_undo_group ();
+ rl_delete (1, c);
+ rl_insert (1, c);
+ rl_end_undo_group ();
+ rl_vi_check ();
+ }
+ else
+ rl_forward (1);
+ }
+ return (0);
+}
+
+rl_vi_put (count, key)
+ int count, key;
+{
+ if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
+ rl_point++;
+
+ rl_yank ();
+ rl_backward (1);
+ return (0);
+}
+
+rl_vi_check ()
+{
+ if (rl_point && rl_point == rl_end)
+ rl_point--;
+ return (0);
+}
+
+rl_vi_column (count, key)
+ int count, key;
+{
+ if (count > rl_end)
+ rl_end_of_line ();
+ 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;
+ c = rl_read_key ();
+ *nextkey = c;
+
+ if (!member (c, vi_motion))
+ {
+ if (digit_p (c))
+ {
+ save = rl_numeric_arg;
+ rl_numeric_arg = digit_value (c);
+ rl_digit_loop1 ();
+ rl_numeric_arg *= save;
+ c = rl_read_key (); /* real command */
+ *nextkey = c;
+ }
+ else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
+ {
+ rl_mark = rl_end;
+ rl_beg_of_line ();
+ _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 ((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 && (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)
+ exchange (rl_point, rl_mark);
+
+ return (0);
+}
+
+/* A simplified loop for vi. Don't dispatch key at end.
+ Don't recognize minus sign? */
+static int
+rl_digit_loop1 ()
+{
+ int key, c;
+
+ while (1)
+ {
+ rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0);
+ key = c = rl_read_key ();
+
+ if (_rl_keymap[c].type == ISFUNC &&
+ _rl_keymap[c].function == rl_universal_argument)
+ {
+ rl_numeric_arg *= 4;
+ continue;
+ }
+
+ c = UNMETA (c);
+ if (digit_p (c))
+ {
+ if (rl_explicit_arg)
+ rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c);
+ else
+ rl_numeric_arg = digit_value (c);
+ rl_explicit_arg = 1;
+ }
+ else
+ {
+ rl_clear_message ();
+ rl_stuff_char (key);
+ break;
+ }
+ }
+ return (0);
+}
+
+rl_vi_delete_to (count, key)
+ int count, key;
+{
+ int c;
+
+ if (uppercase_p (key))
+ rl_stuff_char ('$');
+ else if (vi_redoing)
+ rl_stuff_char (_rl_vi_last_motion);
+
+ if (rl_vi_domove (key, &c))
+ {
+ 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);
+}
+
+rl_vi_change_to (count, key)
+ int count, key;
+{
+ int c, start_pos;
+
+ if (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))
+ {
+ 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 ((to_upper (c) == 'W') && rl_point < start_pos)
+ rl_point = start_pos;
+
+ rl_kill_text (rl_point, rl_mark);
+
+ rl_begin_undo_group ();
+ _rl_vi_doing_insert = 1;
+ _rl_vi_set_last (key, count, rl_arg_sign);
+ rl_vi_insertion_mode (1, key);
+
+ return (0);
+}
+
+rl_vi_yank_to (count, key)
+ int count, key;
+{
+ int c, save = rl_point;
+
+ if (uppercase_p (key))
+ rl_stuff_char ('$');
+
+ if (rl_vi_domove (key, &c))
+ {
+ 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);
+}
+
+rl_vi_delete (count, key)
+ int count, key;
+{
+ int end;
+
+ if (rl_end == 0)
+ {
+ ding ();
+ return -1;
+ }
+
+ 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 (1);
+ return (0);
+}
+
+/* Turn the current line into a comment in shell history.
+ A K*rn shell style function. */
+rl_vi_comment (count, key)
+ int count, key;
+{
+ rl_beg_of_line ();
+
+ if (rl_vi_comment_begin != (char *)NULL)
+ rl_insert_text (rl_vi_comment_begin);
+ else
+ rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
+
+ rl_redisplay ();
+ rl_newline (1, '\n');
+ return (0);
+}
+
+rl_vi_first_print (count, key)
+ int count, key;
+{
+ return (rl_back_to_indent ());
+}
+
+rl_back_to_indent (ignore1, ignore2)
+ int ignore1, ignore2;
+{
+ rl_beg_of_line ();
+ while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
+ rl_point++;
+ return (0);
+}
+
+/* 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 */
+
+rl_vi_char_search (count, key)
+ int count, key;
+{
+ static char target;
+ static int orig_dir, dir;
+ int pos;
+
+ if (key == ';' || key == ',')
+ dir = (key == ';' ? orig_dir : -orig_dir);
+ else
+ {
+ if (vi_redoing)
+ target = _rl_vi_last_search_char;
+ else
+ _rl_vi_last_search_char = target = rl_getc (rl_instream);
+
+ 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;
+ }
+ }
+
+ pos = rl_point;
+
+ while (count--)
+ {
+ if (dir < 0)
+ {
+ if (pos == 0)
+ {
+ ding ();
+ return -1;
+ }
+
+ pos--;
+ do
+ {
+ if (rl_line_buffer[pos] == target)
+ {
+ if (dir == BTO)
+ rl_point = pos + 1;
+ else
+ rl_point = pos;
+ break;
+ }
+ }
+ while (pos--);
+
+ if (pos < 0)
+ {
+ ding ();
+ return -1;
+ }
+ }
+ else
+ { /* dir > 0 */
+ if (pos >= rl_end)
+ {
+ ding ();
+ return -1;
+ }
+
+ pos++;
+ do
+ {
+ if (rl_line_buffer[pos] == target)
+ {
+ if (dir == FTO)
+ rl_point = pos - 1;
+ else
+ rl_point = pos;
+ break;
+ }
+ }
+ while (++pos < rl_end);
+
+ if (pos >= (rl_end - 1))
+ {
+ ding ();
+ return -1;
+ }
+ }
+ }
+ return (0);
+}
+
+/* Match brackets */
+rl_vi_match (ignore, key)
+ int ignore, key;
+{
+ int count = 1, brack, pos;
+
+ pos = rl_point;
+ if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
+ {
+ while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
+ rl_point < rl_end - 1)
+ rl_forward (1);
+
+ if (brack <= 0)
+ {
+ rl_point = pos;
+ ding ();
+ return -1;
+ }
+ }
+
+ pos = rl_point;
+
+ if (brack < 0)
+ {
+ while (count)
+ {
+ if (--pos >= 0)
+ {
+ int b = rl_vi_bracktype (rl_line_buffer[pos]);
+ if (b == -brack)
+ count--;
+ else if (b == brack)
+ count++;
+ }
+ else
+ {
+ ding ();
+ return -1;
+ }
+ }
+ }
+ else
+ { /* brack > 0 */
+ while (count)
+ {
+ if (++pos < rl_end)
+ {
+ int b = rl_vi_bracktype (rl_line_buffer[pos]);
+ if (b == -brack)
+ count--;
+ else if (b == brack)
+ count++;
+ }
+ else
+ {
+ 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;
+ }
+}
+
+rl_vi_change_char (count, key)
+ int count, key;
+{
+ int c;
+
+ if (vi_redoing)
+ c = _rl_vi_last_replacement;
+ else
+ _rl_vi_last_replacement = c = rl_getc (rl_instream);
+
+ if (c == '\033' || c == CTRL ('C'))
+ return -1;
+
+ while (count-- && rl_point < rl_end)
+ {
+ rl_begin_undo_group ();
+
+ rl_delete (1, c);
+ rl_insert (1, c);
+ if (count == 0)
+ rl_backward (1);
+
+ rl_end_undo_group ();
+ }
+ return (0);
+}
+
+rl_vi_subst (count, key)
+ int count, key;
+{
+ rl_begin_undo_group ();
+
+ if (uppercase_p (key))
+ {
+ rl_beg_of_line ();
+ rl_kill_line (1);
+ }
+ else
+ rl_delete_text (rl_point, rl_point+count);
+
+ rl_end_undo_group ();
+
+ _rl_vi_set_last (key, count, rl_arg_sign);
+
+ rl_begin_undo_group ();
+ _rl_vi_doing_insert = 1;
+ rl_vi_insertion_mode (1, key);
+
+ return (0);
+}
+
+rl_vi_overstrike (count, key)
+ int count, key;
+{
+ int i;
+
+ if (_rl_vi_doing_insert == 0)
+ {
+ _rl_vi_doing_insert = 1;
+ rl_begin_undo_group ();
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ vi_replace_count++;
+ rl_begin_undo_group ();
+
+ if (rl_point < rl_end)
+ {
+ rl_delete (1, key);
+ rl_insert (1, key);
+ }
+ else
+ rl_insert (1, key);
+
+ rl_end_undo_group ();
+ }
+ return (0);
+}
+
+rl_vi_overstrike_delete (count)
+ int count;
+{
+ int i, s;
+
+ for (i = 0; i < count; i++)
+ {
+ if (vi_replace_count == 0)
+ {
+ ding ();
+ break;
+ }
+ s = rl_point;
+
+ if (rl_do_undo ())
+ vi_replace_count--;
+
+ if (rl_point == s)
+ rl_backward (1);
+ }
+
+ if (vi_replace_count == 0 && _rl_vi_doing_insert)
+ {
+ rl_end_undo_group ();
+ rl_do_undo ();
+ _rl_vi_doing_insert = 0;
+ }
+ return (0);
+}
+
+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 ;. */
+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] == ';')
+ {
+ ding ();
+ return (0);
+ }
+
+ rl_possible_completions ();
+ rl_point = save_pos;
+
+ return (0);
+}
+#endif
+
+#if defined (STATIC_MALLOC)
+
+/* **************************************************************** */
+/* */
+/* xmalloc and xrealloc () */
+/* */
+/* **************************************************************** */
+
+static void memory_error_and_abort ();
+
+static char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ();
+ return (temp);
+}
+
+static char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)xmalloc (bytes);
+ else
+ temp = (char *)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 ();
+}
+#endif /* STATIC_MALLOC */
+
+#endif /* VI_MODE */
diff --git a/gnu/lib/libreadline/xmalloc.c b/gnu/lib/libreadline/xmalloc.c
new file mode 100644
index 0000000..4f6dc76
--- /dev/null
+++ b/gnu/lib/libreadline/xmalloc.c
@@ -0,0 +1,78 @@
+/* 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#if defined (ALREADY_HAVE_XMALLOC)
+#else
+#include <stdio.h>
+
+#if defined (HAVE_STDLIB_H)
+# include <stdlib.h>
+#else
+# include "ansi_stdlib.h"
+#endif /* HAVE_STDLIB_H */
+
+static void memory_error_and_abort ();
+
+/* **************************************************************** */
+/* */
+/* Memory Allocation and Deallocation. */
+/* */
+/* **************************************************************** */
+
+/* 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. */
+char *
+xmalloc (bytes)
+ int bytes;
+{
+ char *temp = (char *)malloc (bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xmalloc");
+ return (temp);
+}
+
+char *
+xrealloc (pointer, bytes)
+ char *pointer;
+ int bytes;
+{
+ char *temp;
+
+ if (!pointer)
+ temp = (char *)malloc (bytes);
+ else
+ temp = (char *)realloc (pointer, bytes);
+
+ if (!temp)
+ memory_error_and_abort ("xrealloc");
+ return (temp);
+}
+
+static void
+memory_error_and_abort (fname)
+ char *fname;
+{
+ fprintf (stderr, "%s: Out of virtual memory!\n", fname);
+ abort ();
+}
+#endif /* !ALREADY_HAVE_XMALLOC */
diff --git a/gnu/lib/libregex/AUTHORS b/gnu/lib/libregex/AUTHORS
new file mode 100644
index 0000000..058be99
--- /dev/null
+++ b/gnu/lib/libregex/AUTHORS
@@ -0,0 +1,10 @@
+Richard Stallman -- original version and continuing revisions of
+ regex.c and regex.h, and original version of the documentation.
+
+Karl Berry and Kathryn Hargreaves -- extensive modifications to above,
+ and all test files.
+
+Jim Blandy -- original version of re_set_registers, revisions to regex.c.
+
+Joe Arceneaux, David MacKenzie, Mike Haertel, Charles Hannum, and
+probably others -- revisions to regex.c.
diff --git a/gnu/lib/libregex/COPYING b/gnu/lib/libregex/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/gnu/lib/libregex/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ <signature of Ty Coon>, 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/gnu/lib/libregex/ChangeLog b/gnu/lib/libregex/ChangeLog
new file mode 100644
index 0000000..ef919d2
--- /dev/null
+++ b/gnu/lib/libregex/ChangeLog
@@ -0,0 +1,3030 @@
+Fri Apr 2 17:31:59 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * Released version 0.12.
+
+ * regex.c (regerror): If errcode is zero, that's not a valid
+ error code, according to POSIX, but return "Success."
+
+ * regex.c (regerror): Remember to actually fetch the message
+ from re_error_msg.
+
+ * regex.c (regex_compile): Don't use the trick for ".*\n" on
+ ".+\n". Since the latter involves laying an extra choice
+ point, the backward jump isn't adjusted properly.
+
+Thu Mar 25 21:35:18 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * regex.c (regex_compile): In the handle_open and handle_close
+ sections, clear pending_exact to zero.
+
+Tue Mar 9 12:03:07 1993 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu)
+
+ * regex.c (re_search_2): In the loop which searches forward
+ using fastmap, don't forget to cast the character from the
+ string to an unsigned before using it as an index into the
+ translate map.
+
+Thu Jan 14 15:41:46 1993 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu)
+
+ * regex.h: Never define const; let the callers do it.
+ configure.in: Don't define USING_AUTOCONF.
+
+Wed Jan 6 20:49:29 1993 Jim Blandy (jimb@geech.gnu.ai.mit.edu)
+
+ * regex.c (regerror): Abort if ERRCODE is out of range.
+
+Sun Dec 20 16:19:10 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * configure.in: Arrange to #define USING_AUTOCONF.
+ * regex.h: If USING_AUTOCONF is #defined, don't mess with
+ `const' at all; autoconf has taken care of it.
+
+Mon Dec 14 21:40:39 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu)
+
+ * regex.h (RE_SYNTAX_AWK): Fix typo. From Arnold Robbins.
+
+Sun Dec 13 20:35:39 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * regex.c (compile_range): Fetch the range start and end by
+ casting the pattern pointer to an `unsigned char *' before
+ fetching through it.
+
+Sat Dec 12 09:41:01 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * regex.c: Undo change of 12/7/92; it's better for Emacs to
+ #define HAVE_CONFIG_H.
+
+Fri Dec 11 22:00:34 1992 Jim Meyering (meyering@hal.gnu.ai.mit.edu)
+
+ * regex.c: Define and use isascii-protected ctype.h macros.
+
+Fri Dec 11 05:10:38 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * regex.c (re_match_2): Undo Karl's November 10th change; it
+ keeps the group in :\(.*\) from matching :/ properly.
+
+Mon Dec 7 19:44:56 1992 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu)
+
+ * regex.c: #include config.h if either HAVE_CONFIG_H or emacs
+ is #defined.
+
+Tue Dec 1 13:33:17 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * regex.c [HAVE_CONFIG_H]: Include config.h.
+
+Wed Nov 25 23:46:02 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * regex.c (regcomp): Add parens around bitwise & for clarity.
+ Initialize preg->allocated to prevent segv.
+
+Tue Nov 24 09:22:29 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * regex.c: Use HAVE_STRING_H, not USG.
+ * configure.in: Check for string.h, not USG.
+
+Fri Nov 20 06:33:24 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.c (SIGN_EXTEND_CHAR) [VMS]: Back out of this change,
+ since Roland Roberts now says it was a localism.
+
+Mon Nov 16 07:01:36 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.h (const) [!HAVE_CONST]: Test another cpp symbol (from
+ Autoconf) before zapping const.
+
+Sun Nov 15 05:36:42 1992 Jim Blandy (jimb@wookumz.gnu.ai.mit.edu)
+
+ * regex.c, regex.h: Changes for VMS from Roland B Roberts
+ <roberts@nsrl31.nsrl.rochester.edu>.
+
+Thu Nov 12 11:31:15 1992 Karl Berry (karl@cs.umb.edu)
+
+ * Makefile.in (distfiles): Include INSTALL.
+
+Tue Nov 10 09:29:23 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.c (re_match_2): At maybe_pop_jump, if at end of string
+ and pattern, just quit the matching loop.
+
+ * regex.c (LETTER_P): Rename to `WORDCHAR_P'.
+
+ * regex.c (AT_STRINGS_{BEG,END}): Take `d' as an arg; change
+ callers.
+
+ * regex.c (re_match_2) [!emacs]: In wordchar and notwordchar
+ cases, advance d.
+
+Wed Nov 4 15:43:58 1992 Karl Berry (karl@hal.gnu.ai.mit.edu)
+
+ * regex.h (const) [!__STDC__]: Don't define if it's already defined.
+
+Sat Oct 17 19:28:19 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.c (bcmp, bcopy, bzero): Only #define if they are not
+ already #defined.
+
+ * configure.in: Use AC_CONST.
+
+Thu Oct 15 08:39:06 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.h (const) [!const]: Conditionalize.
+
+Fri Oct 2 13:31:42 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.h (RE_SYNTAX_ED): New definition.
+
+Sun Sep 20 12:53:39 1992 Karl Berry (karl@cs.umb.edu)
+
+ * regex.[ch]: remove traces of `longest_p' -- dumb idea to put
+ this into the pattern buffer, as it means parallelism loses.
+
+ * Makefile.in (config.status): use sh to run configure --no-create.
+
+ * Makefile.in (realclean): OK, don't remove configure.
+
+Sat Sep 19 09:05:08 1992 Karl Berry (karl@hayley)
+
+ * regex.c (PUSH_FAILURE_POINT, POP_FAILURE_POINT) [DEBUG]: keep
+ track of how many failure points we push and pop.
+ (re_match_2) [DEBUG]: declare variables for that, and print results.
+ (DEBUG_PRINT4): new macro.
+
+ * regex.h (re_pattern_buffer): new field `longest_p' (to
+ eliminate backtracking if the user doesn't need it).
+ * regex.c (re_compile_pattern): initialize it (to 1).
+ (re_search_2): set it to zero if register information is not needed.
+ (re_match_2): if it's set, don't backtrack.
+
+ * regex.c (re_search_2): update fastmap only after checking that
+ the pattern is anchored.
+
+ * regex.c (re_match_2): do more debugging at maybe_pop_jump.
+
+ * regex.c (re_search_2): cast result of TRANSLATE for use in
+ array subscript.
+
+Thu Sep 17 19:47:16 1992 Karl Berry (karl@geech.gnu.ai.mit.edu)
+
+ * Version 0.11.
+
+Wed Sep 16 08:17:10 1992 Karl Berry (karl@hayley)
+
+ * regex.c (INIT_FAIL_STACK): rewrite as statements instead of a
+ complicated comma expr, to avoid compiler warnings (and also
+ simplify).
+ (re_compile_fastmap, re_match_2): change callers.
+
+ * regex.c (POP_FAILURE_POINT): cast pop of regstart and regend
+ to avoid compiler warnings.
+
+ * regex.h (RE_NEWLINE_ORDINARY): remove this syntax bit, and
+ remove uses.
+ * regex.c (at_{beg,end}line_loc_p): go the last mile: remove
+ the RE_NEWLINE_ORDINARY case which made the ^ in \n^ be an anchor.
+
+Tue Sep 15 09:55:29 1992 Karl Berry (karl@hayley)
+
+ * regex.c (at_begline_loc_p): new fn.
+ (at_endline_loc_p): simplify at_endline_op_p.
+ (regex_compile): in ^/$ cases, call the above.
+
+ * regex.c (POP_FAILURE_POINT): rewrite the fn as a macro again,
+ as lord's profiling indicates the function is 20% of the time.
+ (re_match_2): callers changed.
+
+ * configure.in (AC_MEMORY_H): remove, since we never use memcpy et al.
+
+Mon Sep 14 17:49:27 1992 Karl Berry (karl@hayley)
+
+ * Makefile.in (makeargs): include MFLAGS.
+
+Sun Sep 13 07:41:45 1992 Karl Berry (karl@hayley)
+
+ * regex.c (regex_compile): in \1..\9 case, make it always
+ invalid to use \<digit> if there is no preceding <digit>th subexpr.
+ * regex.h (RE_NO_MISSING_BK_REF): remove this syntax bit.
+
+ * regex.c (regex_compile): remove support for invalid empty groups.
+ * regex.h (RE_NO_EMPTY_GROUPS): remove this syntax bit.
+
+ * regex.c (FREE_VARIABLES) [!REGEX_MALLOC]: define as alloca (0),
+ to reclaim memory.
+
+ * regex.h (RE_SYNTAX_POSIX_SED): don't bother with this.
+
+Sat Sep 12 13:37:21 1992 Karl Berry (karl@hayley)
+
+ * README: incorporate emacs.diff.
+
+ * regex.h (_RE_ARGS) [!__STDC__]: define as empty parens.
+
+ * configure.in: add AC_ALLOCA.
+
+ * Put test files in subdir test, documentation in subdir doc.
+ Adjust Makefile.in and configure.in accordingly.
+
+Thu Sep 10 10:29:11 1992 Karl Berry (karl@hayley)
+
+ * regex.h (RE_SYNTAX_{POSIX_,}SED): new definitions.
+
+Wed Sep 9 06:27:09 1992 Karl Berry (karl@hayley)
+
+ * Version 0.10.
+
+Tue Sep 8 07:32:30 1992 Karl Berry (karl@hayley)
+
+ * xregex.texinfo: put the day of month into the date.
+
+ * Makefile.in (realclean): remove Texinfo-generated files.
+ (distclean): remove empty sorted index files.
+ (clean): remove dvi files, etc.
+
+ * configure.in: test for more Unix variants.
+
+ * fileregex.c: new file.
+ Makefile.in (fileregex): new target.
+
+ * iregex.c (main): move variable decls to smallest scope.
+
+ * regex.c (FREE_VARIABLES): free reg_{,info_}dummy.
+ (re_match_2): check that the allocation for those two succeeded.
+
+ * regex.c (FREE_VAR): replace FREE_NONNULL with this.
+ (FREE_VARIABLES): call it.
+ (re_match_2) [REGEX_MALLOC]: initialize all our vars to NULL.
+
+ * tregress.c (do_match): generalize simple_match.
+ (SIMPLE_NONMATCH): new macro.
+ (SIMPLE_MATCH): change from routine.
+
+ * Makefile.in (regex.texinfo): make file readonly, so we don't
+ edit it by mistake.
+
+ * many files (re_default_syntax): rename to `re_syntax_options';
+ call re_set_syntax instead of assigning to the variable where
+ possible.
+
+Mon Sep 7 10:12:16 1992 Karl Berry (karl@hayley)
+
+ * syntax.skel: don't use prototypes.
+
+ * {configure,Makefile}.in: new files.
+
+ * regex.c: include <string.h> `#if USG || STDC_HEADERS'; remove
+ obsolete test for `POSIX', and test for BSRTING.
+ Include <strings.h> if we are not USG or STDC_HEADERS.
+ Do not include <unistd.h>. What did we ever need that for?
+
+ * regex.h (RE_NO_EMPTY_ALTS): remove this.
+ (RE_SYNTAX_AWK): remove from here, too.
+ * regex.c (regex_compile): remove the check.
+ * xregex.texinfo (Alternation Operator): update.
+ * other.c (test_others): remove tests for this.
+
+ * regex.h (RE_DUP_MAX): undefine if already defined.
+
+ * regex.h: (RE_SYNTAX_POSIX*): redo to allow more operators, and
+ define new syntaxes with the minimal set.
+
+ * syntax.skel (main): used sscanf instead of scanf.
+
+ * regex.h (RE_SYNTAX_*GREP): new definitions from mike.
+
+ * regex.c (regex_compile): initialize the upper bound of
+ intervals at the beginning of the interval, not the end.
+ (From pclink@qld.tne.oz.au.)
+
+ * regex.c (handle_bar): rename to `handle_alt', for consistency.
+
+ * regex.c ({store,insert}_{op1,op2}): new routines (except the last).
+ ({STORE,INSERT}_JUMP{,2}): macros to replace the old routines,
+ which took arguments in different orders, and were generally weird.
+
+ * regex.c (PAT_PUSH*): rename to `BUF_PUSH*' -- we're not
+ appending info to the pattern!
+
+Sun Sep 6 11:26:49 1992 Karl Berry (karl@hayley)
+
+ * regex.c (regex_compile): delete the variable
+ `following_left_brace', since we never use it.
+
+ * regex.c (print_compiled_pattern): don't print the fastmap if
+ it's null.
+
+ * regex.c (re_compile_fastmap): handle
+ `on_failure_keep_string_jump' like `on_failure_jump'.
+
+ * regex.c (re_match_2): in `charset{,_not' case, cast the bit
+ count to unsigned, not unsigned char, in case we have a full
+ 32-byte bit list.
+
+ * tregress.c (simple_match): remove.
+ (simple_test): rename as `simple_match'.
+ (simple_compile): print the error string if the compile failed.
+
+ * regex.c (DO_RANGE): rewrite as a function, `compile_range', so
+ we can debug it. Change pattern characters to unsigned char
+ *'s, and change the range variable to an unsigned.
+ (regex_compile): change calls.
+
+Sat Sep 5 17:40:49 1992 Karl Berry (karl@hayley)
+
+ * regex.h (_RE_ARGS): new macro to put in argument lists (if
+ ANSI) or omit them (if K&R); don't declare routines twice.
+
+ * many files (obscure_syntax): rename to `re_default_syntax'.
+
+Fri Sep 4 09:06:53 1992 Karl Berry (karl@hayley)
+
+ * GNUmakefile (extraclean): new target.
+ (realclean): delete the info files.
+
+Wed Sep 2 08:14:42 1992 Karl Berry (karl@hayley)
+
+ * regex.h: doc fix.
+
+Sun Aug 23 06:53:15 1992 Karl Berry (karl@hayley)
+
+ * regex.[ch] (re_comp): no const in the return type (from djm).
+
+Fri Aug 14 07:25:46 1992 Karl Berry (karl@hayley)
+
+ * regex.c (DO_RANGE): declare variables as unsigned chars, not
+ signed chars (from jimb).
+
+Wed Jul 29 18:33:53 1992 Karl Berry (karl@claude.cs.umb.edu)
+
+ * Version 0.9.
+
+ * GNUmakefile (distclean): do not remove regex.texinfo.
+ (realclean): remove it here.
+
+ * tregress.c (simple_test): initialize buf.buffer.
+
+Sun Jul 26 08:59:38 1992 Karl Berry (karl@hayley)
+
+ * regex.c (push_dummy_failure): new opcode and corresponding
+ case in the various routines. Pushed at the end of
+ alternatives.
+
+ * regex.c (jump_past_next_alt): rename to `jump_past_alt', for
+ brevity.
+ (no_pop_jump): rename to `jump'.
+
+ * regex.c (regex_compile) [DEBUG]: terminate printing of pattern
+ with a newline.
+
+ * NEWS: new file.
+
+ * tregress.c (simple_{compile,match,test}): routines to simplify all
+ these little tests.
+
+ * tregress.c: test for matching as much as possible.
+
+Fri Jul 10 06:53:32 1992 Karl Berry (karl@hayley)
+
+ * Version 0.8.
+
+Wed Jul 8 06:39:31 1992 Karl Berry (karl@hayley)
+
+ * regex.c (SIGN_EXTEND_CHAR): #undef any previous definition, as
+ ours should always work properly.
+
+Mon Jul 6 07:10:50 1992 Karl Berry (karl@hayley)
+
+ * iregex.c (main) [DEBUG]: conditionalize the call to
+ print_compiled_pattern.
+
+ * iregex.c (main): initialize buf.buffer to NULL.
+ * tregress (test_regress): likewise.
+
+ * regex.c (alloca) [sparc]: #if on HAVE_ALLOCA_H instead.
+
+ * tregress.c (test_regress): didn't have jla's test quite right.
+
+Sat Jul 4 09:02:12 1992 Karl Berry (karl@hayley)
+
+ * regex.c (re_match_2): only REGEX_ALLOCATE all the register
+ vectors if the pattern actually has registers.
+ (match_end): new variable to avoid having to use best_regend[0].
+
+ * regex.c (IS_IN_FIRST_STRING): rename to FIRST_STRING_P.
+
+ * regex.c: doc fixes.
+
+ * tregess.c (test_regress): new fastmap test forwarded by rms.
+
+ * tregress.c (test_regress): initialize the fastmap field.
+
+ * tregress.c (test_regress): new test from jla that aborted
+ in re_search_2.
+
+Fri Jul 3 09:10:05 1992 Karl Berry (karl@hayley)
+
+ * tregress.c (test_regress): add tests for translating charsets,
+ from kaoru.
+
+ * GNUmakefile (common): add alloca.o.
+ * alloca.c: new file, copied from bison.
+
+ * other.c (test_others): remove var `buf', since it's no longer used.
+
+ * Below changes from ro@TechFak.Uni-Bielefeld.DE.
+
+ * tregress.c (test_regress): initialize buf.allocated.
+
+ * regex.c (re_compile_fastmap): initialize `succeed_n_p'.
+
+ * GNUmakefile (regex): depend on $(common).
+
+Wed Jul 1 07:12:46 1992 Karl Berry (karl@hayley)
+
+ * Version 0.7.
+
+ * regex.c: doc fixes.
+
+Mon Jun 29 08:09:47 1992 Karl Berry (karl@fosse)
+
+ * regex.c (pop_failure_point): change string vars to
+ `const char *' from `unsigned char *'.
+
+ * regex.c: consolidate debugging stuff.
+ (print_partial_compiled_pattern): avoid enum clash.
+
+Mon Jun 29 07:50:27 1992 Karl Berry (karl@hayley)
+
+ * xmalloc.c: new file.
+ * GNUmakefile (common): add it.
+
+ * iregex.c (print_regs): new routine (from jimb).
+ (main): call it.
+
+Sat Jun 27 10:50:59 1992 Jim Blandy (jimb@pogo.cs.oberlin.edu)
+
+ * xregex.c (re_match_2): When we have accepted a match and
+ restored d from best_regend[0], we need to set dend
+ appropriately as well.
+
+Sun Jun 28 08:48:41 1992 Karl Berry (karl@hayley)
+
+ * tregress.c: rename from regress.c.
+
+ * regex.c (print_compiled_pattern): improve charset case to ease
+ byte-counting.
+ Also, don't distinguish between Emacs and non-Emacs
+ {not,}wordchar opcodes.
+
+ * regex.c (print_fastmap): move here.
+ * test.c: from here.
+ * regex.c (print_{{partial,}compiled_pattern,double_string}):
+ rename from ..._printer. Change calls here and in test.c.
+
+ * regex.c: create from xregex.c and regexinc.c for once and for
+ all, and change the debug fns to be extern, instead of static.
+ * GNUmakefile: remove traces of xregex.c.
+ * test.c: put in externs, instead of including regexinc.c.
+
+ * xregex.c: move interactive main program and scanstring to iregex.c.
+ * iregex.c: new file.
+ * upcase.c, printchar.c: new files.
+
+ * various doc fixes and other cosmetic changes throughout.
+
+ * regexinc.c (compiled_pattern_printer): change variable name,
+ for consistency.
+ (partial_compiled_pattern_printer): print other info about the
+ compiled pattern, besides just the opcodes.
+ * xregex.c (regex_compile) [DEBUG]: print the compiled pattern
+ when we're done.
+
+ * xregex.c (re_compile_fastmap): in the duplicate case, set
+ `can_be_null' and return.
+ Also, set `bufp->can_be_null' according to a new variable,
+ `path_can_be_null'.
+ Also, rewrite main while loop to not test `p != NULL', since
+ we never set it that way.
+ Also, eliminate special `can_be_null' value for the endline case.
+ (re_search_2): don't test for the special value.
+ * regex.h (struct re_pattern_buffer): remove the definition.
+
+Sat Jun 27 15:00:40 1992 Karl Berry (karl@hayley)
+
+ * xregex.c (re_compile_fastmap): remove the `RE_' from
+ `REG_RE_MATCH_NULL_AT_END'.
+ Also, assert the fastmap in the pattern buffer is non-null.
+ Also, reset `succeed_n_p' after we've
+ paid attention to it, instead of every time through the loop.
+ Also, in the `anychar' case, only clear fastmap['\n'] if the
+ syntax says to, and don't return prematurely.
+ Also, rearrange cases in some semblance of a rational order.
+ * regex.h (REG_RE_MATCH_NULL_AT_END): remove the `RE_' from the name.
+
+ * other.c: take bug reports from here.
+ * regress.c: new file for them.
+ * GNUmakefile (test): add it.
+ * main.c (main): new possible test.
+ * test.h (test_type): new value in enum.
+
+Thu Jun 25 17:37:43 1992 Karl Berry (karl@hayley)
+
+ * xregex.c (scanstring) [test]: new function from jimb to allow some
+ escapes.
+ (main) [test]: call it (on the string, not the pattern).
+
+ * xregex.c (main): make return type `int'.
+
+Wed Jun 24 10:43:03 1992 Karl Berry (karl@hayley)
+
+ * xregex.c (pattern_offset_t): change to `int', for the benefit
+ of patterns which compile to more than 2^15 bytes.
+
+ * xregex.c (GET_BUFFER_SPACE): remove spurious braces.
+
+ * xregex.texinfo (Using Registers): put in a stub to ``document''
+ the new function.
+ * regex.h (re_set_registers) [!__STDC__]: declare.
+ * xregex.c (re_set_registers): declare K&R style (also move to a
+ different place in the file).
+
+Mon Jun 8 18:03:28 1992 Jim Blandy (jimb@pogo.cs.oberlin.edu)
+
+ * regex.h (RE_NREGS): Doc fix.
+
+ * xregex.c (re_set_registers): New function.
+ * regex.h (re_set_registers): Declaration for new function.
+
+Fri Jun 5 06:55:18 1992 Karl Berry (karl@hayley)
+
+ * main.c (main): `return 0' instead of `exit (0)'. (From Paul Eggert)
+
+ * regexinc.c (SIGN_EXTEND_CHAR): cast to unsigned char.
+ (extract_number, EXTRACT_NUMBER): don't bother to cast here.
+
+Tue Jun 2 07:37:53 1992 Karl Berry (karl@hayley)
+
+ * Version 0.6.
+
+ * Change copyrights to `1985, 89, ...'.
+
+ * regex.h (REG_RE_MATCH_NULL_AT_END): new macro.
+ * xregex.c (re_compile_fastmap): initialize `can_be_null' to
+ `p==pend', instead of in the test at the top of the loop (as
+ it was, it was always being set).
+ Also, set `can_be_null'=1 if we would jump to the end of the
+ pattern in the `on_failure_jump' cases.
+ (re_search_2): check if `can_be_null' is 1, not nonzero. This
+ was the original test in rms' regex; why did we change this?
+
+ * xregex.c (re_compile_fastmap): rename `is_a_succeed_n' to
+ `succeed_n_p'.
+
+Sat May 30 08:09:08 1992 Karl Berry (karl@hayley)
+
+ * xregex.c (re_compile_pattern): declare `regnum' as `unsigned',
+ not `regnum_t', for the benefit of those patterns with more
+ than 255 groups.
+
+ * xregex.c: rename `failure_stack' to `fail_stack', for brevity;
+ likewise for `match_nothing' to `match_null'.
+
+ * regexinc.c (REGEX_REALLOCATE): take both the new and old
+ sizes, and copy only the old bytes.
+ * xregex.c (DOUBLE_FAILURE_STACK): pass both old and new.
+ * This change from Thorsten Ohl.
+
+Fri May 29 11:45:22 1992 Karl Berry (karl@hayley)
+
+ * regexinc.c (SIGN_EXTEND_CHAR): define as `(signed char) c'
+ instead of relying on __CHAR_UNSIGNED__, to work with
+ compilers other than GCC. From Per Bothner.
+
+ * main.c (main): change return type to `int'.
+
+Mon May 18 06:37:08 1992 Karl Berry (karl@hayley)
+
+ * regex.h (RE_SYNTAX_AWK): typo in RE_RE_UNMATCHED...
+
+Fri May 15 10:44:46 1992 Karl Berry (karl@hayley)
+
+ * Version 0.5.
+
+Sun May 3 13:54:00 1992 Karl Berry (karl@hayley)
+
+ * regex.h (struct re_pattern_buffer): now it's just `regs_allocated'.
+ (REGS_UNALLOCATED, REGS_REALLOCATE, REGS_FIXED): new constants.
+ * xregex.c (regexec, re_compile_pattern): set the field appropriately.
+ (re_match_2): and use it. bufp can't be const any more.
+
+Fri May 1 15:43:09 1992 Karl Berry (karl@hayley)
+
+ * regexinc.c: unconditionally include <sys/types.h>, first.
+
+ * regex.h (struct re_pattern_buffer): rename
+ `caller_allocated_regs' to `regs_allocated_p'.
+ * xregex.c (re_compile_pattern): same change here.
+ (regexec): and here.
+ (re_match_2): reallocate registers if necessary.
+
+Fri Apr 10 07:46:50 1992 Karl Berry (karl@hayley)
+
+ * regex.h (RE_SYNTAX{_POSIX,}_AWK): new definitions from Arnold.
+
+Sun Mar 15 07:34:30 1992 Karl Berry (karl at hayley)
+
+ * GNUmakefile (dist): versionize regex.{c,h,texinfo}.
+
+Tue Mar 10 07:05:38 1992 Karl Berry (karl at hayley)
+
+ * Version 0.4.
+
+ * xregex.c (PUSH_FAILURE_POINT): always increment the failure id.
+ (DEBUG_STATEMENT) [DEBUG]: execute the statement even if `debug'==0.
+
+ * xregex.c (pop_failure_point): if the saved string location is
+ null, keep the current value.
+ (re_match_2): at fail, test for a dummy failure point by
+ checking the restored pattern value, not string value.
+ (re_match_2): new case, `on_failure_keep_string_jump'.
+ (regex_compile): output this opcode in the .*\n case.
+ * regexinc.c (re_opcode_t): define the opcode.
+ (partial_compiled_pattern_pattern): add the new case.
+
+Mon Mar 9 09:09:27 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (regex_compile): optimize .*\n to output an
+ unconditional jump to the ., instead of pushing failure points
+ each time through the loop.
+
+ * xregex.c (DOUBLE_FAILURE_STACK): compute the maximum size
+ ourselves (and correctly); change callers.
+
+Sun Mar 8 17:07:46 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (failure_stack_elt_t): change to `const char *', to
+ avoid warnings.
+
+ * regex.h (re_set_syntax): declare this.
+
+ * xregex.c (pop_failure_point) [DEBUG]: conditionally pass the
+ original strings and sizes; change callers.
+
+Thu Mar 5 16:35:35 1992 Karl Berry (karl at claude.cs.umb.edu)
+
+ * xregex.c (regnum_t): new type for register/group numbers.
+ (compile_stack_elt_t, regex_compile): use it.
+
+ * xregex.c (regexec): declare len as `int' to match re_search.
+
+ * xregex.c (re_match_2): don't declare p1 twice.
+
+ * xregex.c: change `while (1)' to `for (;;)' to avoid silly
+ compiler warnings.
+
+ * regex.h [__STDC__]: use #if, not #ifdef.
+
+ * regexinc.c (REGEX_REALLOCATE): cast the result of alloca to
+ (char *), to avoid warnings.
+
+ * xregex.c (regerror): declare variable as const.
+
+ * xregex.c (re_compile_pattern, re_comp): define as returning a const
+ char *.
+ * regex.h (re_compile_pattern, re_comp): likewise.
+
+Thu Mar 5 15:57:56 1992 Karl Berry (karl@hal)
+
+ * xregex.c (regcomp): declare `syntax' as unsigned.
+
+ * xregex.c (re_match_2): try to avoid compiler warnings about
+ unsigned comparisons.
+
+ * GNUmakefile (test-xlc): new target.
+
+ * regex.h (reg_errcode_t): remove trailing comma from definition.
+ * regexinc.c (re_opcode_t): likewise.
+
+Thu Mar 5 06:56:07 1992 Karl Berry (karl at hayley)
+
+ * GNUmakefile (dist): add version numbers automatically.
+ (versionfiles): new variable.
+ (regex.{c,texinfo}): don't add version numbers here.
+ * regex.h: put in placeholder instead of the version number.
+
+Fri Feb 28 07:11:33 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (re_error_msg): declare const, since it is.
+
+Sun Feb 23 05:41:57 1992 Karl Berry (karl at fosse)
+
+ * xregex.c (PAT_PUSH{,_2,_3}, ...): cast args to avoid warnings.
+ (regex_compile, regexec): return REG_NOERROR, instead
+ of 0, on success.
+ (boolean): define as char, and #define false and true.
+ * regexinc.c (STREQ): cast the result.
+
+Sun Feb 23 07:45:38 1992 Karl Berry (karl at hayley)
+
+ * GNUmakefile (test-cc, test-hc, test-pcc): new targets.
+
+ * regex.inc (extract_number, extract_number_and_incr) [DEBUG]:
+ only define if we are debugging.
+
+ * xregex.c [_AIX]: do #pragma alloca first if necessary.
+ * regexinc.c [_AIX]: remove the #pragma from here.
+
+ * regex.h (reg_syntax_t): declare as unsigned, and redo the enum
+ as #define's again. Some compilers do stupid things with enums.
+
+Thu Feb 20 07:19:47 1992 Karl Berry (karl at hayley)
+
+ * Version 0.3.
+
+ * xregex.c, regex.h (newline_anchor_match_p): rename to
+ `newline_anchor'; dumb idea to change the name.
+
+Tue Feb 18 07:09:02 1992 Karl Berry (karl at hayley)
+
+ * regexinc.c: go back to original, i.e., don't include
+ <string.h> or define strchr.
+ * xregex.c (regexec): don't bother with adding characters after
+ newlines to the fastmap; instead, just don't use a fastmap.
+ * xregex.c (regcomp): set the buffer and fastmap fields to zero.
+
+ * xregex.texinfo (GNU r.e. compiling): have to initialize more
+ than two fields.
+
+ * regex.h (struct re_pattern_buffer): rename `newline_anchor' to
+ `newline_anchor_match_p', as we're back to two cases.
+ * xregex.c (regcomp, re_compile_pattern, re_comp): change
+ accordingly.
+ (re_match_2): at begline and endline, POSIX is not a special
+ case anymore; just check newline_anchor_match_p.
+
+Thu Feb 13 16:29:33 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (*empty_string*): rename to *null_string*, for brevity.
+
+Wed Feb 12 06:36:22 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (re_compile_fastmap): at endline, don't set fastmap['\n'].
+ (re_match_2): rewrite the begline/endline cases to take account
+ of the new field newline_anchor.
+
+Tue Feb 11 14:34:55 1992 Karl Berry (karl at hayley)
+
+ * regexinc.c [!USG etc.]: include <strings.h> and define strchr
+ as index.
+
+ * xregex.c (re_search_2): when searching backwards, declare `c'
+ as a char and use casts when using it as an array subscript.
+
+ * xregex.c (regcomp): if REG_NEWLINE, set
+ RE_HAT_LISTS_NOT_NEWLINE. Set the `newline_anchor' field
+ appropriately.
+ (regex_compile): compile [^...] as matching a \n according to
+ the syntax bit.
+ (regexec): if doing REG_NEWLINE stuff, compile a fastmap and add
+ characters after any \n's to the newline.
+ * regex.h (RE_HAT_LISTS_NOT_NEWLINE): new syntax bit.
+ (struct re_pattern_buffer): rename `posix_newline' to
+ `newline_anchor', define constants for its values.
+
+Mon Feb 10 07:22:50 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (re_compile_fastmap): combine the code at the top and
+ bottom of the loop, as it's essentially identical.
+
+Sun Feb 9 10:02:19 1992 Karl Berry (karl at hayley)
+
+ * xregex.texinfo (POSIX Translate Tables): remove this, as it
+ doesn't match the spec.
+
+ * xregex.c (re_compile_fastmap): if we finish off a path, go
+ back to the top (to set can_be_null) instead of returning
+ immediately.
+
+ * xregex.texinfo: changes from bob.
+
+Sat Feb 1 07:03:25 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (re_search_2): doc fix (from rms).
+
+Fri Jan 31 09:52:04 1992 Karl Berry (karl at hayley)
+
+ * xregex.texinfo (GNU Searching): clarify the range arg.
+
+ * xregex.c (re_match_2, at_endline_op_p): add extra parens to
+ get rid of GCC 2's (silly, IMHO) warning about && within ||.
+
+ * xregex.c (common_op_match_empty_string_p): use
+ MATCH_NOTHING_UNSET_VALUE, not -1.
+
+Thu Jan 16 08:43:02 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (SET_REGS_MATCHED): only set the registers from
+ lowest to highest.
+
+ * regexinc.c (MIN): new macro.
+ * xregex.c (re_match_2): only check min (num_regs,
+ regs->num_regs) when we set the returned regs.
+
+ * xregex.c (re_match_2): set registers after the first
+ num_regs to -1 before we return.
+
+Tue Jan 14 16:01:42 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (re_match_2): initialize max (RE_NREGS, re_nsub + 1)
+ registers (from rms).
+
+ * xregex.c, regex.h: don't abbreviate `19xx' to `xx'.
+
+ * regexinc.c [!emacs]: include <sys/types.h> before <unistd.h>.
+ (from ro@thp.Uni-Koeln.DE).
+
+Thu Jan 9 07:23:00 1992 Karl Berry (karl at hayley)
+
+ * xregex.c (*unmatchable): rename to `match_empty_string_p'.
+ (CAN_MATCH_NOTHING): rename to `REG_MATCH_EMPTY_STRING_P'.
+
+ * regexinc.c (malloc, realloc): remove prototypes, as they can
+ cause clashes (from rms).
+
+Mon Jan 6 12:43:24 1992 Karl Berry (karl at claude.cs.umb.edu)
+
+ * Version 0.2.
+
+Sun Jan 5 10:50:38 1992 Karl Berry (karl at hayley)
+
+ * xregex.texinfo: bring more or less up-to-date.
+ * GNUmakefile (regex.texinfo): generate from regex.h and
+ xregex.texinfo.
+ * include.awk: new file.
+
+ * xregex.c: change all calls to the fn extract_number_and_incr
+ to the macro.
+
+ * xregex.c (re_match_2) [emacs]: in at_dot, use PTR_CHAR_POS + 1,
+ instead of bf_* and sl_*. Cast d to unsigned char *, to match
+ the declaration in Emacs' buffer.h.
+ [emacs19]: in before_dot, at_dot, and after_dot, likewise.
+
+ * regexinc.c: unconditionally include <sys/types.h>.
+
+ * regexinc.c (alloca) [!alloca]: Emacs config files sometimes
+ define this, so don't define it if it's already defined.
+
+Sun Jan 5 06:06:53 1992 Karl Berry (karl at fosse)
+
+ * xregex.c (re_comp): fix type conflicts with regex_compile (we
+ haven't been compiling this).
+
+ * regexinc.c (SIGN_EXTEND_CHAR): use `__CHAR_UNSIGNED__', not
+ `CHAR_UNSIGNED'.
+
+ * regexinc.c (NULL) [!NULL]: define it (as zero).
+
+ * regexinc.c (extract_number): remove the temporaries.
+
+Sun Jan 5 07:50:14 1992 Karl Berry (karl at hayley)
+
+ * regex.h (regerror) [!__STDC__]: return a size_t, not a size_t *.
+
+ * xregex.c (PUSH_FAILURE_POINT, ...): declare `destination' as
+ `char *' instead of `void *', to match alloca declaration.
+
+ * xregex.c (regerror): use `size_t' for the intermediate values
+ as well as the return type.
+
+ * xregex.c (regexec): cast the result of malloc.
+
+ * xregex.c (regexec): don't initialize `private_preg' in the
+ declaration, as old C compilers can't do that.
+
+ * xregex.c (main) [test]: declare printchar void.
+
+ * xregex.c (assert) [!DEBUG]: define this to do nothing, and
+ remove #ifdef DEBUG's from around asserts.
+
+ * xregex.c (re_match_2): remove error message when not debugging.
+
+Sat Jan 4 09:45:29 1992 Karl Berry (karl at hayley)
+
+ * other.c: test the bizarre duplicate case in re_compile_fastmap
+ that I just noticed.
+
+ * test.c (general_test): don't test registers beyond the end of
+ correct_regs, as well as regs.
+
+ * xregex.c (regex_compile): at handle_close, don't assign to
+ *inner_group_loc if we didn't push a start_memory (because the
+ group number was too big). In fact, don't push or pop the
+ inner_group_offset in that case.
+
+ * regex.c: rename to xregex.c, since it's not the whole thing.
+ * regex.texinfo: likewise.
+ * GNUmakefile: change to match.
+
+ * regex.c [DEBUG]: only include <stdio.h> if debugging.
+
+ * regexinc.c (SIGN_EXTEND_CHAR) [CHAR_UNSIGNED]: if it's already
+ defined, don't redefine it.
+
+ * regex.c: define _GNU_SOURCE at the beginning.
+ * regexinc.c (isblank) [!isblank]: define it.
+ (isgraph) [!isgraph]: change conditional to this, and remove the
+ sequent stuff.
+
+ * regex.c (regex_compile): add `blank' character class.
+
+ * regex.c (regex_compile): don't use a uchar variable to loop
+ through all characters.
+
+ * regex.c (regex_compile): at '[', improve logic for checking
+ that we have enough space for the charset.
+
+ * regex.h (struct re_pattern_buffer): declare translate as char
+ * again. We only use it as an array subscript once, I think.
+
+ * regex.c (TRANSLATE): new macro to cast the data character
+ before subscripting.
+ (num_internal_regs): rename to `num_regs'.
+
+Fri Jan 3 07:58:01 1992 Karl Berry (karl at hayley)
+
+ * regex.h (struct re_pattern_buffer): declare `allocated' and
+ `used' as unsigned long, since these are never negative.
+
+ * regex.c (compile_stack_element): rename to compile_stack_elt_t.
+ (failure_stack_element): similarly.
+
+ * regexinc.c (TALLOC, RETALLOC): new macros to simplify
+ allocation of arrays.
+
+ * regex.h (re_*) [__STDC__]: don't declare string args unsigned
+ char *; that makes them incompatible with string constants.
+ (struct re_pattern_buffer): declare the pattern and translate
+ table as unsigned char *.
+ * regex.c (most routines): use unsigned char vs. char consistently.
+
+ * regex.h (re_compile_pattern): do not declare the length arg as
+ const.
+ * regex.c (re_compile_pattern): likewise.
+
+ * regex.c (POINTER_TO_REG): rename to `POINTER_TO_OFFSET'.
+
+ * regex.h (re_registers): declare `start' and `end' as
+ `regoff_t', instead of `int'.
+
+ * regex.c (regexec): if either of the malloc's for the register
+ information fail, return failure.
+
+ * regex.h (RE_NREGS): define this again, as 30 (from jla).
+ (RE_ALLOCATE_REGISTERS): remove this.
+ (RE_SYNTAX_*): remove it from definitions.
+ (re_pattern_buffer): remove `return_default_num_regs', add
+ `caller_allocated_regs'.
+ * regex.c (re_compile_pattern): clear no_sub and
+ caller_allocated_regs in the pattern.
+ (regcomp): set caller_allocated_regs.
+ (re_match_2): do all register allocation at the end of the
+ match; implement new semantics.
+
+ * regex.c (MAX_REGNUM): new macro.
+ (regex_compile): at handle_open and handle_close, if the group
+ number is too large, don't push the start/stop memory.
+
+Thu Jan 2 07:56:10 1992 Karl Berry (karl at hayley)
+
+ * regex.c (re_match_2): if the back reference is to a group that
+ never matched, then goto fail, not really_fail. Also, don't
+ test if the pattern can match the empty string. Why did we
+ ever do that?
+ (really_fail): this label no longer needed.
+
+ * regexinc.c [STDC_HEADERS]: use only this to test if we should
+ include <stdlib.h>.
+
+ * regex.c (DO_RANGE, regex_compile): translate in all cases
+ except the single character after a \.
+
+ * regex.h (RE_AWK_CLASS_HACK): rename to
+ RE_BACKSLASH_ESCAPE_IN_LISTS.
+ * regex.c (regex_compile): change use.
+
+ * regex.c (re_compile_fastmap): do not translate the characters
+ again; we already translated them at compilation. (From ylo@ngs.fi.)
+
+ * regex.c (re_match_2): in case for at_dot, invert sense of
+ comparison and find the character number properly. (From
+ worley@compass.com.)
+ (re_match_2) [emacs]: remove the cases for before_dot and
+ after_dot, since there's no way to specify them, and the code
+ is wrong (judging from this change).
+
+Wed Jan 1 09:13:38 1992 Karl Berry (karl at hayley)
+
+ * psx-{interf,basic,extend}.c, other.c: set `t' as the first
+ thing, so that if we run them in sucession, general_test's
+ kludge to see if we're doing POSIX tests works.
+
+ * test.h (test_type): add `all_test'.
+ * main.c: add case for `all_test'.
+
+ * regexinc.c (partial_compiled_pattern_printer,
+ double_string_printer): don't print anything if we're passed null.
+
+ * regex.c (PUSH_FAILURE_POINT): do not scan for the highest and
+ lowest active registers.
+ (re_match_2): compute lowest/highest active regs at start_memory and
+ stop_memory.
+ (NO_{LOW,HIGH}EST_ACTIVE_REG): new sentinel values.
+ (pop_failure_point): return the lowest/highest active reg values
+ popped; change calls.
+
+ * regex.c [DEBUG]: include <assert.h>.
+ (various routines) [DEBUG]: change conditionals to assertions.
+
+ * regex.c (DEBUG_STATEMENT): new macro.
+ (PUSH_FAILURE_POINT): use it to increment num_regs_pushed.
+ (re_match_2) [DEBUG]: only declare num_regs_pushed if DEBUG.
+
+ * regex.c (*can_match_nothing): rename to *unmatchable.
+
+ * regex.c (re_match_2): at stop_memory, adjust argument reading.
+
+ * regex.h (re_pattern_buffer): declare `can_be_null' as a 2-bit
+ bit field.
+
+ * regex.h (re_pattern_buffer): declare `buffer' unsigned char *;
+ no, dumb idea. The pattern can have signed number.
+
+ * regex.c (re_match_2): in maybe_pop_jump case, skip over the
+ right number of args to the group operators, and don't do
+ anything with endline if posix_newline is not set.
+
+ * regex.c, regexinc.c (all the things we just changed): go back
+ to putting the inner group count after the start_memory,
+ because we need it in the on_failure_jump case in re_match_2.
+ But leave it after the stop_memory also, since we need it
+ there in re_match_2, and we don't have any way of getting back
+ to the start_memory.
+
+ * regexinc.c (partial_compiled_pattern_printer): adjust argument
+ reading for start/stop_memory.
+ * regex.c (re_compile_fastmap, group_can_match_nothing): likewise.
+
+Tue Dec 31 10:15:08 1991 Karl Berry (karl at hayley)
+
+ * regex.c (bits list routines): remove these.
+ (re_match_2): get the number of inner groups from the pattern,
+ instead of keeping track of it at start and stop_memory.
+ Put the count after the stop_memory, not after the
+ start_memory.
+ (compile_stack_element): remove `fixup_inner_group' member,
+ since we now put it in when we can compute it.
+ (regex_compile): at handle_open, don't push the inner group
+ offset, and at handle_close, don't pop it.
+
+ * regex.c (level routines): remove these, and their uses in
+ regex_compile. This was another manifestation of having to find
+ $'s that were endlines.
+
+ * regex.c (regexec): this does searching, not matching (a
+ well-disguised part of the standard). So rewrite to use
+ `re_search' instead of `re_match'.
+ * psx-interf.c (test_regexec): add tests to, uh, match.
+
+ * regex.h (RE_TIGHT_ALT): remove this; nobody uses it.
+ * regex.c: remove the code that was supposed to implement it.
+
+ * other.c (test_others): ^ and $ never match newline characters;
+ RE_CONTEXT_INVALID_OPS doesn't affect anchors.
+
+ * psx-interf.c (test_regerror): update for new error messages.
+
+ * psx-extend.c: it's now ok to have an alternative be just a $,
+ so remove all the tests which supposed that was invalid.
+
+Wed Dec 25 09:00:05 1991 Karl Berry (karl at hayley)
+
+ * regex.c (regex_compile): in handle_open, don't skip over ^ and
+ $ when checking for an empty group. POSIX has changed the
+ grammar.
+ * psx-extend.c (test_posix_extended): thus, move (^$) tests to
+ valid section.
+
+ * regexinc.c (boolean): move from here to test.h and regex.c.
+ * test files: declare verbose, omit_register_tests, and
+ test_should_match as boolean.
+
+ * psx-interf.c (test_posix_c_interface): remove the `c_'.
+ * main.c: likewise.
+
+ * psx-basic.c (test_posix_basic): ^ ($) is an anchor after
+ (before) an open (close) group.
+
+ * regex.c (re_match_2): in endline, correct precedence of
+ posix_newline condition.
+
+Tue Dec 24 06:45:11 1991 Karl Berry (karl at hayley)
+
+ * test.h: incorporate private-tst.h.
+ * test files: include test.h, not private-tst.h.
+
+ * test.c (general_test): set posix_newline to zero if we are
+ doing POSIX tests (unfortunately, it's difficult to call
+ regcomp in this case, which is what we should really be doing).
+
+ * regex.h (reg_syntax_t): make this an enumeration type which
+ defines the syntax bits; renames re_syntax_t.
+
+ * regex.c (at_endline_op_p): don't preincrement p; then if it's
+ not an empty string op, we lose.
+
+ * regex.h (reg_errcode_t): new enumeration type of the error
+ codes.
+ * regex.c (regex_compile): return that type.
+
+ * regex.c (regex_compile): in [, initialize
+ just_had_a_char_class to false; somehow I had changed this to
+ true.
+
+ * regex.h (RE_NO_CONSECUTIVE_REPEATS): remove this, since we
+ don't use it, and POSIX doesn't require this behavior anymore.
+ * regex.c (regex_compile): remove it from here.
+
+ * regex.c (regex_compile): remove the no_op insertions for
+ verify_and_adjust_endlines, since that doesn't exist anymore.
+
+ * regex.c (regex_compile) [DEBUG]: use printchar to print the
+ pattern, so unprintable bytes will print properly.
+
+ * regex.c: move re_error_msg back.
+ * test.c (general_test): print the compile error if the pattern
+ was invalid.
+
+Mon Dec 23 08:54:53 1991 Karl Berry (karl at hayley)
+
+ * regexinc.c: move re_error_msg here.
+
+ * regex.c (re_error_msg): the ``message'' for success must be
+ NULL, to keep the interface to re_compile_pattern the same.
+ (regerror): if the msg is null, use "Success".
+
+ * rename most test files for consistency. Change Makefile
+ correspondingly.
+
+ * test.c (most routines): add casts to (unsigned char *) when we
+ call re_{match,search}{,_2}.
+
+Sun Dec 22 09:26:06 1991 Karl Berry (karl at hayley)
+
+ * regex.c (re_match_2): declare string args as unsigned char *
+ again; don't declare non-pointer args const; declare the
+ pattern buffer const.
+ (re_match): likewise.
+ (re_search_2, re_search): likewise, except don't declare the
+ pattern const, since we make a fastmap.
+ * regex.h [__STDC__]: change prototypes.
+
+ * regex.c (regex_compile): return an error code, not a string.
+ (re_err_list): new table to map from error codes to string.
+ (re_compile_pattern): return an element of re_err_list.
+ (regcomp): don't test all the strings.
+ (regerror): just use the list.
+ (put_in_buffer): remove this.
+
+ * regex.c (equivalent_failure_points): remove this.
+
+ * regex.c (re_match_2): don't copy the string arguments into
+ non-const pointers. We never alter the data.
+
+ * regex.c (re_match_2): move assignment to `is_a_jump_n' out of
+ the main loop. Just initialize it right before we do
+ something with it.
+
+ * regex.[ch] (re_match_2): don't declare the int parameters const.
+
+Sat Dec 21 08:52:20 1991 Karl Berry (karl at hayley)
+
+ * regex.h (re_syntax_t): new type; declare to be unsigned
+ (previously we used int, but since we do bit operations on
+ this, unsigned is better, according to H&S).
+ (obscure_syntax, re_pattern_buffer): use that type.
+ * regex.c (re_set_syntax, regex_compile): likewise.
+
+ * regex.h (re_pattern_buffer): new field `posix_newline'.
+ * regex.c (re_comp, re_compile_pattern): set to zero.
+ (regcomp): set to REG_NEWLINE.
+ * regex.h (RE_HAT_LISTS_NOT_NEWLINE): remove this (we can just
+ check `posix_newline' instead.)
+
+ * regex.c (op_list_type, op_list, add_op): remove these.
+ (verify_and_adjust_endlines): remove this.
+ (pattern_offset_list_type, *pattern_offset* routines): and these.
+ These things all implemented the nonleading/nontrailing position
+ code, which was very long, had a few remaining problems, and
+ is no longer needed. So...
+
+ * regexinc.c (STREQ): new macro to abbreviate strcmp(,)==0, for
+ brevity. Change various places in regex.c to use it.
+
+ * regex{,inc}.c (enum regexpcode): change to a typedef
+ re_opcode_t, for brevity.
+
+ * regex.h (re_syntax_table) [SYNTAX_TABLE]: remove this; it
+ should only be in regex.c, I think, since we don't define it
+ in this case. Maybe it should be conditional on !SYNTAX_TABLE?
+
+ * regexinc.c (partial_compiled_pattern_printer): simplify and
+ distinguish the emacs/not-emacs (not)wordchar cases.
+
+Fri Dec 20 08:11:38 1991 Karl Berry (karl at hayley)
+
+ * regexinc.c (regexpcode) [emacs]: only define the Emacs opcodes
+ if we are ifdef emacs.
+
+ * regex.c (BUF_PUSH*): rename to PAT_PUSH*.
+
+ * regex.c (regex_compile): in $ case, go back to essentially the
+ original code for deciding endline op vs. normal char.
+ (at_endline_op_p): new routine.
+ * regex.h (RE_ANCHORS_ONLY_AT_ENDS, RE_CONTEXT_INVALID_ANCHORS,
+ RE_REPEATED_ANCHORS_AWAY, RE_NO_ANCHOR_AT_NEWLINE): remove
+ these. POSIX has simplified the rules for anchors in draft
+ 11.2.
+ (RE_NEWLINE_ORDINARY): new syntax bit.
+ (RE_CONTEXT_INDEP_ANCHORS): change description to be compatible
+ with POSIX.
+ * regex.texinfo (Syntax Bits): remove the descriptions.
+
+Mon Dec 16 08:12:40 1991 Karl Berry (karl at hayley)
+
+ * regex.c (re_match_2): in jump_past_next_alt, unconditionally
+ goto no_pop. The only register we were finding was one which
+ enclosed the whole alternative expression, not one around an
+ individual alternative. So we were never doing what we
+ thought we were doing, and this way makes (|a) against the
+ empty string fail.
+
+ * regex.c (regex_compile): remove `highest_ever_regnum', and
+ don't restore regnum from the stack; just put it into a
+ temporary to put into the stop_memory. Otherwise, groups
+ aren't numbered consecutively.
+
+ * regex.c (is_in_compile_stack): rename to
+ `group_in_compile_stack'; remove unnecessary test for the
+ stack being empty.
+
+ * regex.c (re_match_2): in on_failure_jump, skip no_op's before
+ checking for the start_memory, in case we were called from
+ succeed_n.
+
+Sun Dec 15 16:20:48 1991 Karl Berry (karl at hayley)
+
+ * regex.c (regex_compile): in duplicate case, use
+ highest_ever_regnum instead of regnum, since the latter is
+ reverted at stop_memory.
+
+ * regex.c (re_match_2): in on_failure_jump, if the * applied to
+ a group, save the information for that group and all inner
+ groups (by making it active), even though we're not inside it
+ yet.
+
+Sat Dec 14 09:50:59 1991 Karl Berry (karl at hayley)
+
+ * regex.c (PUSH_FAILURE_ITEM, POP_FAILURE_ITEM): new macros.
+ Use them instead of copying the stack manipulating a zillion
+ times.
+
+ * regex.c (PUSH_FAILURE_POINT, pop_failure_point) [DEBUG]: save
+ and restore a unique identification value for each failure point.
+
+ * regexinc.c (partial_compiled_pattern_printer): don't print an
+ extra / after duplicate commands.
+
+ * regex.c (regex_compile): in back-reference case, allow a back
+ reference to register `regnum'. Otherwise, even `\(\)\1'
+ fails, since regnum is 1 at the back-reference.
+
+ * regex.c (re_match_2): in fail, don't examine the pattern if we
+ restored to pend.
+
+ * test_private.h: rename to private_tst.h. Change includes.
+
+ * regex.c (extend_bits_list): compute existing size for realloc
+ in bytes, not blocks.
+
+ * regex.c (re_match_2): in jump_past_next_alt, the for loop was
+ missing its (empty) statement. Even so, some register tests
+ still fail, although in a different way than in the previous change.
+
+Fri Dec 13 15:55:08 1991 Karl Berry (karl at hayley)
+
+ * regex.c (re_match_2): in jump_past_next_alt, unconditionally
+ goto no_pop, since we weren't properly detecting if the
+ alternative matched something anyway. No, we need to not jump
+ to keep the register values correct; just change to not look at
+ register zero and not test RE_NO_EMPTY_ALTS (which is a
+ compile-time thing).
+
+ * regex.c (SET_REGS_MATCHED): start the loop at 1, since we never
+ care about register zero until the very end. (I think.)
+
+ * regex.c (PUSH_FAILURE_POINT, pop_failure_point): go back to
+ pushing and popping the active registers, instead of only doing
+ the registers before a group: (fooq|fo|o)*qbar against fooqbar
+ fails, since we restore back into the middle of group 1, yet it
+ isn't active, because the previous restore clobbered the active flag.
+
+Thu Dec 12 17:25:36 1991 Karl Berry (karl at hayley)
+
+ * regex.c (PUSH_FAILURE_POINT): do not call
+ `equivalent_failure_points' after all; it causes the registers
+ to be ``wrong'' (according to POSIX), and an infinite loop on
+ `((a*)*)*' against `ab'.
+
+ * regex.c (re_compile_fastmap): don't push `pend' on the failure
+ stack.
+
+Tue Dec 10 10:30:03 1991 Karl Berry (karl at hayley)
+
+ * regex.c (PUSH_FAILURE_POINT): if pushing same failure point that
+ is on the top of the stack, fail.
+ (equivalent_failure_points): new routine.
+
+ * regex.c (re_match_2): add debug statements for every opcode we
+ execute.
+
+ * regex.c (regex_compile/handle_close): restore
+ `fixup_inner_group_count' and `regnum' from the stack.
+
+Mon Dec 9 13:51:15 1991 Karl Berry (karl at hayley)
+
+ * regex.c (PUSH_FAILURE_POINT): declare `this_reg' as int, so
+ unsigned arithmetic doesn't happen when we don't want to save
+ the registers.
+
+Tue Dec 3 08:11:10 1991 Karl Berry (karl at hayley)
+
+ * regex.c (extend_bits_list): divide size by bits/block.
+
+ * regex.c (init_bits_list): remove redundant assignmen to
+ `bits_list_ptr'.
+
+ * regexinc.c (partial_compiled_pattern_printer): don't do *p++
+ twice in the same expr.
+
+ * regex.c (re_match_2): at on_failure_jump, use the correct
+ pattern positions for getting the stuff following the start_memory.
+
+ * regex.c (struct register_info): remove the bits_list for the
+ inner groups; make that a separate variable.
+
+Mon Dec 2 10:42:07 1991 Karl Berry (karl at hayley)
+
+ * regex.c (PUSH_FAILURE_POINT): don't pass `failure_stack' as an
+ arg; change callers.
+
+ * regex.c (PUSH_FAILURE_POINT): print items in order they are
+ pushed.
+ (pop_failure_point): likewise.
+
+ * regex.c (main): prompt for the pattern and string.
+
+ * regex.c (FREE_VARIABLES) [!REGEX_MALLOC]: declare as nothing;
+ remove #ifdefs from around calls.
+
+ * regex.c (extract_number, extract_number_and_incr): declare static.
+
+ * regex.c: remove the canned main program.
+ * main.c: new file.
+ * Makefile (COMMON): add main.o.
+
+Tue Sep 24 06:26:51 1991 Kathy Hargreaves (kathy at fosse)
+
+ * regex.c (re_match_2): Made `pend' and `dend' not register variables.
+ Only set string2 to string1 if string1 isn't null.
+ Send address of p, d, regstart, regend, and reg_info to
+ pop_failure_point.
+ Put in more debug statements.
+
+ * regex.c [debug]: Added global variable.
+ (DEBUG_*PRINT*): Only print if `debug' is true.
+ (DEBUG_DOUBLE_STRING_PRINTER): Changed DEBUG_STRING_PRINTER's
+ name to this.
+ Changed some comments.
+ (PUSH_FAILURE_POINT): Moved and added some debugging statements.
+ Was saving regstart on the stack twice instead of saving both
+ regstart and regend; remedied this.
+ [NUM_REGS_ITEMS]: Changed from 3 to 4, as now save lowest and
+ highest active registers instead of highest used one.
+ [NUM_NON_REG_ITEMS]: Changed name of NUM_OTHER_ITEMS to this.
+ (NUM_FAILURE_ITEMS): Use active registers instead of number 0
+ through highest used one.
+ (re_match_2): Have pop_failure_point put things in the variables.
+ (pop_failure_point): Have it do what the fail case in re_match_2
+ did with the failure stack, instead of throwing away the stuff
+ popped off. re_match_2 can ignore results when it doesn't
+ need them.
+
+
+Thu Sep 5 13:23:28 1991 Kathy Hargreaves (kathy at fosse)
+
+ * regex.c (banner): Changed copyright years to be separate.
+
+ * regex.c [CHAR_UNSIGNED]: Put __ at both ends of this name.
+ [DEBUG, debug_count, *debug_p, DEBUG_PRINT_1, DEBUG_PRINT_2,
+ DEBUG_COMPILED_PATTERN_PRINTER ,DEBUG_STRING_PRINTER]:
+ defined these for debugging.
+ (extract_number): Added this (debuggable) routine version of
+ the macro EXTRACT_NUMBER. Ditto for EXTRACT_NUMBER_AND_INCR.
+ (re_compile_pattern): Set return_default_num_regs if the
+ syntax bit RE_ALLOCATE_REGISTERS is set.
+ [REGEX_MALLOC]: Renamed USE_ALLOCA to this.
+ (BUF_POP): Got rid of this, as don't ever use it.
+ (regex_compile): Made the type of `pattern' not be register.
+ If DEBUG, print the pattern to compile.
+ (re_match_2): If had a `$' in the pattern before a `^' then
+ don't record the `^' as an anchor.
+ Put (enum regexpcode) before references to b, as suggested
+ [RE_NO_BK_BRACES]: Changed RE_NO_BK_CURLY_BRACES to this.
+ (remove_pattern_offset): Removed this unused routine.
+ (PUSH_FAILURE_POINT): Changed to only save active registers.
+ Put in debugging statements.
+ (re_compile_fastmap): Made `pattern' not a register variable.
+ Use routine for extracting numbers instead of macro.
+ (re_match_2): Made `p', `mcnt' and `mcnt2' not register variables.
+ Added `num_regs_pushed' for debugging.
+ Only malloc registers if the syntax bit RE_ALLOCATE_REGISTERS is set.
+ Put in debug statements.
+ Put the macro NOTE_INNER_GROUP's code inline, as it was the
+ only called in one place.
+ For debugging, extract numbers using routines instead of macros.
+ In case fail: only restore pushed active registers, and added
+ debugging statements.
+ (pop_failure_point): Test for underfull stack.
+ (group_can_match_nothing, common_op_can_match_nothing): For
+ debugging, extract numbers using routines instead of macros.
+ (regexec): Changed formal parameters to not be prototypes.
+ Don't initialize `regs' or `private_preg' in their declarations.
+
+Tue Jul 23 18:38:36 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h [RE_CONTEX_INDEP_OPS]: Moved the anchor stuff out of
+ this bit.
+ [RE_UNMATCHED_RIGHT_PAREN_ORD]: Defined this bit.
+ [RE_CONTEXT_INVALID_ANCHORS]: Defined this bit.
+ [RE_CONTEXT_INDEP_ANCHORS]: Defined this bit.
+ Added RE_CONTEXT_INDEP_ANCHORS to all syntaxes which had
+ RE_CONTEXT_INDEP_OPS.
+ Took RE_ANCHORS_ONLY_AT_ENDS out of the POSIX basic syntax.
+ Added RE_UNMATCHED_RIGHT_PAREN_ORD to the POSIX extended
+ syntax.
+ Took RE_REPEATED_ANCHORS_AWAY out of the POSIX extended syntax.
+ Defined REG_NOERROR (which will probably have to go away again).
+ Changed the type `off_t' to `regoff_t'.
+
+ * regex.c: Changed some commments.
+ (regex_compile): Added variable `had_an_endline' to keep track
+ of if hit a `$' since the beginning of the pattern or the last
+ alternative (if any).
+ Changed RE_CONTEXT_INVALID_OPS and RE_CONTEXT_INDEP_OPS to
+ RE_CONTEXT_INVALID_ANCHORS and RE_CONTEXT_INDEP_ANCHORS where
+ appropriate.
+ Put a `no_op' in the pattern if a repeat is only zero or one
+ times; in this case and if it is many times (whereupon a jump
+ backwards is pushed instead), keep track of the operator for
+ verify_and_adjust_endlines.
+ If RE_UNMATCHED_RIGHT_PAREN is set, make an unmatched
+ close-group operator match `)'.
+ Changed all error exits to exit (1).
+ (remove_pattern_offset): Added this routine, but don't use it.
+ (verify_and_adjust_endlines): At top of routine, if initialize
+ routines run out of memory, return true after setting
+ enough_memory false.
+ At end of endline, et al. case, don't set *p to no_op.
+ Repetition operators also set the level and active groups'
+ match statuses, unless RE_REPEATED_ANCHORS_AWAY is set.
+ (get_group_match_status): Put a return in front of call to get_bit.
+ (re_compile_fastmap): Changed is_a_succeed_n to a boolean.
+ If at end of pattern, then if the failure stack isn't empty,
+ go back to the failure point.
+ In *jump* case, only pop the stack if what's on top of it is
+ where we've just jumped to.
+ (re_search_2): Return -2 instead of val if val is -2.
+ (group_can_match_nothing, alternative_can_match_nothing,
+ common_op_can-match_nothing): Now pass in reg_info for the
+ `duplicate' case.
+ (re_match_2): Don't skip over the next alternative also if
+ empty alternatives aren't allowed.
+ In fail case, if failed to a backwards jump that's part of a
+ repetition loop, pop the current failure point and use the
+ next one.
+ (pop_failure_point): Check that there's as many register items
+ on the failure stack as the stack says there are.
+ (common_op_can_match_nothing): Added variables `ret' and
+ `reg_no' so can set reg_info for the group encountered.
+ Also break without doing anything if hit a no_op or the other
+ kinds of `endline's.
+ If not done already, set reg_info in start_memory case.
+ Put in no_pop_jump for an optimized succeed_n of zero repetitions.
+ In succeed_n case, if the number isn't zero, then return false.
+ Added `duplicate' case.
+
+Sat Jul 13 11:27:38 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (REG_NOERROR): Added this error code definition.
+
+ * regex.c: Took some redundant parens out of macros.
+ (enum regexpcode): Added jump_past_next_alt.
+ Wrapped some macros in `do..while (0)'.
+ Changed some comments.
+ (regex_compile): Use `fixup_alt_jump' instead of `fixup_jump'.
+ Use `maybe_pop_jump' instead of `maybe_pop_failure_jump'.
+ Use `jump_past_next_alt' instead of `no_pop_jump' when at the
+ end of an alternative.
+ (re_match_2): Used REGEX_ALLOCATE for the registers stuff.
+ In stop_memory case: Add more boolean tests to see if the
+ group is in a loop.
+ Added jump_past_next_alt case, which doesn't jump over the
+ next alternative if the last one didn't match anything.
+ Unfortunately, to make this work with, e.g., `(a+?*|b)*'
+ against `bb', I also had to pop the alternative's failure
+ point, which in turn broke backtracking!
+ In fail case: Detect a dummy failure point by looking at
+ failure_stack.avail - 2, not stack[-2].
+ (pop_failure_point): Only pop if the stack isn't empty; don't
+ give an error if it is. (Not sure yet this is correct.)
+ (group_can_match_nothing): Make it return a boolean instead of int.
+ Make it take an argument indicating the end of where it should look.
+ If find a group that can match nothing, set the pointer
+ argument to past the group in the pattern.
+ Took out cases which can share with alternative_can_match_nothing
+ and call common_op_can_match_nothing.
+ Took ++ out of switch, so could call common_op_can_match_nothing.
+ Wrote lots more for on_failure_jump case to handle alternatives.
+ Main loop now doesn't look for matching stop_memory, but
+ rather the argument END; return true if hit the matching
+ stop_memory; this way can call itself for inner groups.
+ (alternative_can_match_nothing): Added for alternatives.
+ (common_op_can_match_nothing): Added for previous two routines'
+ common operators.
+ (regerror): Returns a message saying there's no error if gets
+ sent REG_NOERROR.
+
+Wed Jul 3 10:43:15 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: Removed unnecessary enclosing parens from several macros.
+ Put `do..while (0)' around a few.
+ Corrected some comments.
+ (INIT_FAILURE_STACK_SIZE): Deleted in favor of using
+ INIT_FAILURE_ALLOC.
+ (INIT_FAILURE_STACK, DOUBLE_FAILURE_STACK, PUSH_PATTERN_OP,
+ PUSH_FAILURE_POINT): Made routines of the same name (but with all
+ lowercase letters) into these macros, so could use `alloca'
+ when USE_ALLOCA is defined. The reason is stated below for
+ bits lists. Deleted analogous routines.
+ (re_compile_fastmap): Added variable void *destination for
+ PUSH_PATTERN_OP.
+ (re_match_2): Added variable void *destination for REGEX_REALLOCATE.
+ Used the failure stack macros in place of the routines.
+ Detected a dummy failure point by inspecting the failure stack's
+ (avail - 2)th element, not failure_stack.stack[-2]. This bug
+ arose when used the failure stack macros instead of the routines.
+
+ * regex.c [USE_ALLOCA]: Put this conditional around previous
+ alloca stuff and defined these to work differently depending
+ on whether or not USE_ALLOCA is defined:
+ (REGEX_ALLOCATE): Uses either `alloca' or `malloc'.
+ (REGEX_REALLOCATE): Uses either `alloca' or `realloc'.
+ (INIT_BITS_LIST, EXTEND_BITS_LIST, SET_BIT_TO_VALUE): Defined
+ macro versions of routines with the same name (only with all
+ lowercase letters) so could use `alloc' in re_match_2. This
+ is to prevent core leaks when C-g is used in Emacs and to make
+ things faster and avoid storage fragmentation. These things
+ have to be macros because the results of `alloca' go away with
+ the routine by which it's called.
+ (BITS_BLOCK_SIZE, BITS_BLOCK, BITS_MASK): Moved to above the
+ above-mentioned macros instead of before the routines defined
+ below regex_compile.
+ (set_bit_to_value): Compacted some code.
+ (reg_info_type): Changed inner_groups field to be bits_list_type
+ so could be arbitrarily long and thus handle arbitrary nesting.
+ (NOTE_INNER_GROUP): Put `do...while (0)' around it so could
+ use as a statement.
+ Changed code to use bits lists.
+ Added variable void *destination for REGEX_REALLOCATE (whose call
+ is several levels in).
+ Changed variable name of `this_bit' to `this_reg'.
+ (FREE_VARIABLES): Only define and use if USE_ALLOCA is defined.
+ (re_match_2): Use REGEX_ALLOCATE instead of malloc.
+ Instead of setting INNER_GROUPS of reg_info to zero, have to
+ use INIT_BITS_LIST and return -2 (and free variables if
+ USE_ALLOCA isn't defined) if it fails.
+
+Fri Jun 28 13:45:07 1991 Karl Berry (karl at hayley)
+
+ * regex.c (re_match_2): set value of `dend' when we restore `d'.
+
+ * regex.c: remove declaration of alloca.
+
+ * regex.c (MISSING_ISGRAPH): rename to `ISGRAPH_MISSING'.
+
+ * regex.h [_POSIX_SOURCE]: remove these conditionals; always
+ define POSIX stuff.
+ * regex.c (_POSIX_SOURCE): change conditionals to use `POSIX'
+ instead.
+
+Sat Jun 1 16:56:50 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.*: Changed RE_CONTEXTUAL_* to RE_CONTEXT_*,
+ RE_TIGHT_VBAR to RE_TIGHT_ALT, RE_NEWLINE_OR to
+ RE_NEWLINE_ALT, and RE_DOT_MATCHES_NEWLINE to RE_DOT_NEWLINE.
+
+Wed May 29 09:24:11 1991 Karl Berry (karl at hayley)
+
+ * regex.texinfo (POSIX Pattern Buffers): cross-reference the
+ correct node name (Match-beginning-of-line, not ..._line).
+ (Syntax Bits): put @code around all syntax bits.
+
+Sat May 18 16:29:58 1991 Karl Berry (karl at hayley)
+
+ * regex.c (global): add casts to keep broken compilers from
+ complaining about malloc and realloc calls.
+
+ * regex.c (isgraph) [MISSING_ISGRAPH]: change test to this,
+ instead of `#ifndef isgraph', since broken compilers can't
+ have both a macro and a symbol by the same name.
+
+ * regex.c (re_comp, re_exec) [_POSIX_SOURCE]: do not define.
+ (regcomp, regfree, regexec, regerror) [_POSIX_SOURCE && !emacs]:
+ only define in this case.
+
+Mon May 6 17:37:04 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (re_search, re_search_2): Changed BUFFER to not be const.
+
+ * regex.c (re_compile_pattern): `^' is in a leading position if
+ it precedes a newline.
+ (various routines): Added or changed header comments.
+ (double_pattern_offsets_list): Changed name from
+ `extend_pattern_offsets_list'.
+ (adjust_pattern_offsets_list): Changed return value from
+ unsigned to void.
+ (verify_and_adjust_endlines): Now returns `true' and `false'
+ instead of 1 and 0.
+ `$' is in a leading position if it follows a newline.
+ (set_bit_to_value, get_bit_value): Exit with error if POSITION < 0
+ so now calling routines don't have to.
+ (init_failure_stack, inspect_failure_stack_top,
+ pop_failure_stack_top, push_pattern_op, double_failure_stack):
+ Now return value unsigned instead of boolean.
+ (re_search, re_search_2): Changed BUFP to not be const.
+ (re_search_2): Added variable const `private_bufp' to send to
+ re_match_2.
+ (push_failure_point): Made return value unsigned instead of boolean.
+
+Sat May 4 15:32:22 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (re_compile_fastmap): Added extern for this.
+ Changed some comments.
+
+ * regex.c (re_compile_pattern): In case handle_bar: put invalid
+ pattern test before levels matching stuff.
+ Changed some commments.
+ Added optimizing test for detecting an empty alternative that
+ ends with a trailing '$' at the end of the pattern.
+ (re_compile_fastmap): Moved failure_stack stuff to before this
+ so could use it. Made its stack dynamic.
+ Made it return an int so that it could return -2 if its stack
+ couldn't be allocated.
+ Added to header comment (about the return values).
+ (init_failure_stack): Wrote so both re_match_2 and
+ re_compile_fastmap could use it similar stacks.
+ (double_failure_stack): Added for above reasons.
+ (push_pattern_op): Wrote for re_compile_fastmap.
+ (re_search_2): Now return -2 if re_compile_fastmap does.
+ (re_match_2): Made regstart and regend type failure_stack_element*.
+ (push_failure_point): Made pattern_place and string_place type
+ failure_stack_element*.
+ Call double_failure_stack now.
+ Return true instead of 1.
+
+Wed May 1 12:57:21 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (remove_intervening_anchors): Avoid erroneously making
+ ops into no_op's by making them no_op only when they're beglines.
+ (verify_and_adjust_endlines): Don't make '$' a normal character
+ if it's before a newline.
+ Look for the endline op in *p, not p[1].
+ (failure_stack_element): Added this declaration.
+ (failure_stack_type): Added this declaration.
+ (INIT_FAILURE_STACK_SIZE, FAILURE_STACK_EMPTY,
+ FAILURE_STACK_PTR_EMPTY, REMAINING_AVAIL_SLOTS): Added for
+ failure stack.
+ (FAILURE_ITEM_SIZE, PUSH_FAILURE_POINT): Deleted.
+ (FREE_VARIABLES): Now free failure_stack.stack instead of stackb.
+ (re_match_2): deleted variables `initial_stack', `stackb',
+ `stackp', and `stacke' and added `failure_stack' to replace them.
+ Replaced calls to PUSH_FAILURE_POINT with those to
+ push_failure_point.
+ (push_failure_point): Added for re_match_2.
+ (pop_failure_point): Rewrote to use a failure_stack_type of stack.
+ (can_match_nothing): Moved definition to below re_match_2.
+ (bcmp_translate): Moved definition to below re_match_2.
+
+Mon Apr 29 14:20:54 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (enum regexpcode): Added codes endline_before_newline
+ and repeated_endline_before_newline so could detect these
+ types of endlines in the intermediate stages of a compiled
+ pattern.
+ (INIT_FAILURE_ALLOC): Renamed NFAILURES to this and set it to 5.
+ (BUF_PUSH): Put `do {...} while 0' around this.
+ (BUF_PUSH_2): Defined this to cut down on expansion of EXTEND_BUFFER.
+ (regex_compile): Changed some comments.
+ Now push endline_before_newline if find a `$' before a newline
+ in the pattern.
+ If a `$' might turn into an ordinary character, set laststart
+ to point to it.
+ In '^' case, if syntax bit RE_TIGHT_VBAR is set, then for `^'
+ to be in a leading position, it must be first in the pattern.
+ Don't have to check in one of the else clauses that it's not set.
+ If RE_CONTEXTUAL_INDEP_OPS isn't set but RE_ANCHORS_ONLY_AT_ENDS
+ is, make '^' a normal character if it isn't first in the pattern.
+ Can only detect at the end if a '$' after an alternation op is a
+ trailing one, so can't immediately detect empty alternatives
+ if a '$' follows a vbar.
+ Added a picture of the ``success jumps'' in alternatives.
+ Have to set bufp->used before calling verify_and_adjust_endlines.
+ Also do it before returning all error strings.
+ (remove_intervening_anchors): Now replaces the anchor with
+ repeated_endline_before_newline if it's an endline_before_newline.
+ (verify_and_adjust_endlines): Deleted SYNTAX parameter (could
+ use bufp's) and added GROUP_FORWARD_MATCH_STATUS so could
+ detect back references referring to empty groups.
+ Added variable `bend' to point past the end of the pattern buffer.
+ Added variable `previous_p' so wouldn't have to reinspect the
+ pattern buffer to see what op we just looked at.
+ Added endline_before_newline and repeated_endline_before_newline
+ cases.
+ When checking if in a trailing position, added case where '$'
+ has to be at the pattern's end if either of the syntax bits
+ RE_ANCHORS_ONLY_AT_ENDS or RE_TIGHT_VBAR are set.
+ Since `endline' can have the intermediate form `endline_in_repeat',
+ have to change it to `endline' if RE_REPEATED_ANCHORS_AWAY
+ isn't set.
+ Now disallow empty alternatives with trailing endlines in them
+ if RE_NO_EMPTY_ALTS is set.
+ Now don't make '$' an ordinary character if it precedes a newline.
+ Don't make it an ordinary character if it's before a newline.
+ Back references now affect the level matching something only if
+ they refer to nonempty groups.
+ (can_match_nothing): Now increment p1 in the switch, which
+ changes many of the cases, but makes the code more like what
+ it was derived from.
+ Adjust the return statement to reflect above.
+ (struct register_info): Made `can_match_nothing' field an int
+ instead of a bit so could have -1 in it if never set.
+ (MAX_FAILURE_ITEMS): Changed name from MAX_NUM_FAILURE_ITEMS.
+ (FAILURE_ITEM_SIZE): Defined how much space a failure items uses.
+ (PUSH_FAILURE_POINT): Changed variable `last_used_reg's name
+ to `highest_used_reg'.
+ Added variable `num_stack_items' and changed `len's name to
+ `stack_length'.
+ Test failure stack limit in terms of number of items in it, not
+ in terms of its length. rms' fix tested length against number
+ of items, which was a misunderstanding.
+ Use `realloc' instead of `alloca' to extend the failure stack.
+ Use shifts instead of multiplying by 2.
+ (FREE_VARIABLES): Free `stackb' instead of `initial_stack', as
+ might may have been reallocated.
+ (re_match_2): When mallocing `initial_stack', now multiply
+ the number of items wanted (what was there before) by
+ FAILURE_ITEM_SIZE.
+ (pop_failure_point): Need this procedure form of the macro of
+ the same name for debugging, so left it in and deleted the
+ macro.
+ (recomp): Don't free the pattern buffer's translate field.
+
+Mon Apr 15 09:47:47 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_DUP_MAX): Moved to outside of #ifdef _POSIX_SOURCE.
+ * regex.c (#include <sys/types.h>): Removed #ifdef _POSIX_SOURCE
+ condition.
+ (malloc, realloc): Made return type void* #ifdef __STDC__.
+ (enum regexpcode): Added endline_in_repeat for the compiler's
+ use; this never ends up on the final compiled pattern.
+ (INIT_PATTERN_OFFSETS_LIST_SIZE): Initial size for
+ pattern_offsets_list_type.
+ (pattern_offset_type): Type for pattern offsets.
+ (pattern_offsets_list_type): Type for keeping a list of
+ pattern offsets.
+ (anchor_list_type): Changed to above type.
+ (PATTERN_OFFSETS_LIST_PTR_FULL): Tests if a pattern offsets
+ list is full.
+ (ANCHOR_LIST_PTR_FULL): Changed to above.
+ (BIT_BLOCK_SIZE): Changed to BITS_BLOCK_SIZE and moved to
+ above bits list routines below regex_compile.
+ (op_list_type): Defined to be pattern_offsets_list_type.
+ (compile_stack_type): Changed offsets to be
+ pattern_offset_type instead of unsigned.
+ (pointer): Changed the name of all structure fields from this
+ to `avail'.
+ (COMPILE_STACK_FULL): Changed so the stack is full if `avail'
+ is equal to `size' instead of `size' - 1.
+ (GET_BUFFER_SPACE): Changed `>=' to `>' in the while statement.
+ (regex_compile): Added variable `enough_memory' so could check
+ that routine that verifies '$' positions could return an
+ allocation error.
+ (group_count): Deleted this variable, as `regnum' already does
+ this work.
+ (op_list): Added this variable to keep track of operations
+ needed for verifying '$' positions.
+ (anchor_list): Now initialize using routine
+ `init_pattern_offsets_list'.
+ Consolidated the three bits_list initializations.
+ In case '$': Instead of trying to go past constructs which can
+ follow '$', merely detect the special case where it has to be
+ at the pattern's end, fix up any fixup jumps if necessary,
+ record the anchor if necessary and add an `endline' (and
+ possibly two `no-op's) to the pattern; will call a routine at
+ the end to verify if it's in a valid position or not.
+ (init_pattern_offsets_list): Added to initialize pattern
+ offsets lists.
+ (extend_anchor_list): Renamed this extend_pattern_offsets_list
+ and renamed parameters and internal variables appropriately.
+ (add_pattern_offset): Added this routine which both
+ record_anchor_position and add_op call.
+ (adjust_pattern_offsets_list): Add this routine to adjust by
+ some increment all the pattern offsets a list of such after a
+ given position.
+ (record_anchor_position): Now send in offset instead of
+ calculating it and just call add_pattern_offset.
+ (adjust_anchor_list): Replaced by above routine.
+ (remove_intervening_anchors): If the anchor is an `endline'
+ then replace it with `endline_in_repeat' instead of `no_op'.
+ (add_op): Added this routine to call in regex_compile
+ wherever push something relevant to verifying '$' positions.
+ (verify_and_adjust_endlines): Added routine to (1) verify that
+ '$'s in a pattern buffer (represented by `endline') were in
+ valid positions and (2) whether or not they were anchors.
+ (BITS_BLOCK_SIZE): Renamed BIT_BLOCK_SIZE and moved to right
+ above bits list routines.
+ (BITS_BLOCK): Defines which array element of a bits list the
+ bit corresponding to a given position is in.
+ (BITS_MASK): Has a 1 where the bit (in a bit list array element)
+ for a given position is.
+
+Mon Apr 1 12:09:06 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (BIT_BLOCK_SIZE): Defined this for using with
+ bits_list_type, abstracted from level_list_type so could use
+ for more things than just the level match status.
+ (regex_compile): Renamed `level_list' variable to
+ `level_match_status'.
+ Added variable `group_match_status' of type bits_list_type.
+ Kept track of whether or not for all groups any of them
+ matched other than the empty string, so detect if a back
+ reference in front of a '^' made it nonleading or not.
+ Do this by setting a match status bit for all active groups
+ whenever leave a group that matches other than the empty string.
+ Could detect which groups are active by going through the
+ stack each time, but or-ing a bits list of active groups with
+ a bits list of group match status is faster, so make a bits
+ list of active groups instead.
+ Have to check that '^' isn't in a leading position before
+ going to normal_char.
+ Whenever set level match status of the current level, also set
+ the match status of all active groups.
+ Increase the group count and make that group active whenever
+ open a group.
+ When close a group, only set the next level down if the
+ current level matches other than the empty string, and make
+ the current group inactive.
+ At a back reference, only set a level's match status if the
+ group to which the back reference refers matches other than
+ the empty string.
+ (init_bits_list): Added to initialize a bits list.
+ (get_level_value): Deleted this. (Made into
+ get_level_match_status.)
+ (extend_bits_list): Added to extend a bits list. (Made this
+ from deleted routine `extend_level_list'.)
+ (get_bit): Added to get a bit value from a bits list. (Made
+ this from deleted routine `get_level_value'.)
+ (set_bit_to_value): Added to set a bit in a bits list. (Made
+ this from deleted routine `set_level_value'.)
+ (get_level_match_status): Added this to get the match status
+ of a given level. (Made from get_level_value.)
+ (set_this_level, set_next_lower_level): Made all routines
+ which set bits extend the bits list if necessary, thus they
+ now return an unsigned value to indicate whether or not the
+ reallocation failed.
+ (increase_level): No longer extends the level list.
+ (make_group_active): Added to mark as active a given group in
+ an active groups list.
+ (make_group_inactive): Added to mark as inactive a given group
+ in an active groups list.
+ (set_match_status_of_active_groups): Added to set the match
+ status of all currently active groups.
+ (get_group_match_status): Added to get a given group's match status.
+ (no_levels_match_anything): Removed the paramenter LEVEL.
+ (PUSH_FAILURE_POINT): Added rms' bug fix and changed RE_NREGS
+ to num_internal_regs.
+
+Sun Mar 31 09:04:30 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_ANCHORS_ONLY_AT_ENDS): Added syntax so could
+ constrain '^' and '$' to only be anchors if at the beginning
+ and end of the pattern.
+ (RE_SYNTAX_POSIX_BASIC): Added the above bit.
+
+ * regex.c (enum regexcode): Changed `unused' to `no_op'.
+ (this_and_lower_levels_match_nothing): Deleted forward reference.
+ (regex_compile): case '^': if the syntax bit RE_ANCHORS_ONLY_AT_ENDS
+ is set, then '^' is only an anchor if at the beginning of the
+ pattern; only record anchor position if the syntax bit
+ RE_REPEATED_ANCHORS_AWAY is set; the '^' is a normal char if
+ the syntax bit RE_ANCHORS_ONLY_AT_END is set and we're not at
+ the beginning of the pattern (and neither RE_CONTEXTUAL_INDEP_OPS
+ nor RE_CONTEXTUAL_INDEP_OPS syntax bits are set).
+ Only adjust the anchor list if the syntax bit
+ RE_REPEATED_ANCHORS_AWAY is set.
+
+ * regex.c (level_list_type): Use to detect when '^' is
+ in a leading position.
+ (regex_compile): Added level_list_type level_list variable in
+ which we keep track of whether or not a grouping level (in its
+ current or most recent incarnation) matches anything besides the
+ empty string. Set the bit for the i-th level when detect it
+ should match something other than the empty string and the bit
+ for the (i-1)-th level when leave the i-th group. Clear all
+ bits for the i-th and higher levels if none of 0--(i - 1)-th's
+ bits are set when encounter an alternation operator on that
+ level. If no levels are set when hit a '^', then it is in a
+ leading position. We keep track of which level we're at by
+ increasing a variable current_level whenever we encounter an
+ open-group operator and decreasing it whenever we encounter a
+ close-group operator.
+ Have to adjust the anchor list contents whenever insert
+ something ahead of them (such as on_failure_jump's) in the
+ pattern.
+ (adjust_anchor_list): Adjusts the offsets in an anchor list by
+ a given increment starting at a given start position.
+ (get_level_value): Returns the bit setting of a given level.
+ (set_level_value): Sets the bit of a given level to a given value.
+ (set_this_level): Sets (to 1) the bit of a given level.
+ (set_next_lower_level): Sets (to 1) the bit of (LEVEL - 1) for a
+ given LEVEL.
+ (clear_this_and_higher_levels): Clears the bits for a given
+ level and any higher levels.
+ (extend_level_list): Adds sizeof(unsigned) more bits to a level list.
+ (increase_level): Increases by 1 the value of a given level variable.
+ (decrease_level): Decreases by 1 the value of a given level variable.
+ (lower_levels_match_nothing): Checks if any levels lower than
+ the given one match anything.
+ (no_levels_match_anything): Checks if any levels match anything.
+ (re_match_2): At case wordbeg: before looking at d-1, check that
+ we're not at the string's beginning.
+ At case wordend: Added some illuminating parentheses.
+
+Mon Mar 25 13:58:51 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NO_ANCHOR_AT_NEWLINE): Changed syntax bit name
+ from RE_ANCHOR_NOT_NEWLINE because an anchor never matches the
+ newline itself, just the empty string either before or after it.
+ (RE_REPEATED_ANCHORS_AWAY): Added this syntax bit for ignoring
+ anchors inside groups which are operated on by repetition
+ operators.
+ (RE_DOT_MATCHES_NEWLINE): Added this bit so the match-any-character
+ operator could match a newline when it's set.
+ (RE_SYNTAX_POSIX_BASIC): Set RE_DOT_MATCHES_NEWLINE in this.
+ (RE_SYNTAX_POSIX_EXTENDED): Set RE_DOT_MATCHES_NEWLINE and
+ RE_REPEATED_ANCHORS_AWAY in this.
+ (regerror): Changed prototypes to new POSIX spec.
+
+ * regex.c (anchor_list_type): Added so could null out anchors inside
+ repeated groups.
+ (ANCHOR_LIST_PTR_FULL): Added for above type.
+ (compile_stack_element): Changed name from stack_element.
+ (compile_stack_type): Changed name from compile_stack.
+ (INIT_COMPILE_STACK_SIZE): Changed name from INIT_STACK_SIZE.
+ (COMPILE_STACK_EMPTY): Changed name from STACK_EMPTY.
+ (COMPILE_STACK_FULL): Changed name from STACK_FULL.
+ (regex_compile): Changed SYNTAX parameter to non-const.
+ Changed variable name `stack' to `compile_stack'.
+ If syntax bit RE_REPEATED_ANCHORS_AWAY is set, then naively put
+ anchors in a list when encounter them and then set them to
+ `unused' when detect they are within a group operated on by a
+ repetition operator. Need something more sophisticated than
+ this, as they should only get set to `unused' if they are in
+ positions where they would be anchors. Also need a better way to
+ detect contextually invalid anchors.
+ Changed some commments.
+ (is_in_compile_stack): Changed name from `is_in_stack'.
+ (extend_anchor_list): Added to do anchor stuff.
+ (record_anchor_position): Added to do anchor stuff.
+ (remove_intervening_anchors): Added to do anchor stuff.
+ (re_match_2): Now match a newline with the match-any-character
+ operator if RE_DOT_MATCHES_NEWLINE is set.
+ Compacted some code.
+ (regcomp): Added new POSIX newline information to the header
+ commment.
+ If REG_NEWLINE cflag is set, then now unset RE_DOT_MATCHES_NEWLINE
+ in syntax.
+ (put_in_buffer): Added to do new POSIX regerror spec. Called
+ by regerror.
+ (regerror): Changed to take a pattern buffer, error buffer and
+ its size, and return type `size_t', the size of the full error
+ message, and the first ERRBUF_SIZE - 1 characters of the full
+ error message in the error buffer.
+
+Wed Feb 27 16:38:33 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (#include <sys/types.h>): Removed this as new POSIX
+ standard has the user include it.
+ (RE_SYNTAX_POSIX_BASIC and RE_SYNTAX_POSIX_EXTENDED): Removed
+ RE_HAT_LISTS_NOT_NEWLINE as new POSIX standard has the cflag
+ REG_NEWLINE now set this. Similarly, added syntax bit
+ RE_ANCHOR_NOT_NEWLINE as this is now unset by REG_NEWLINE.
+ (RE_SYNTAX_POSIX_BASIC): Removed syntax bit
+ RE_NO_CONSECUTIVE_REPEATS as POSIX now allows them.
+
+ * regex.c (#include <sys/types.h>): Added this as new POSIX
+ standard has the user include it instead of us putting it in
+ regex.h.
+ (extern char *re_syntax_table): Made into an extern so the
+ user could allocate it.
+ (DO_RANGE): If don't find a range end, now goto invalid_range_end
+ instead of unmatched_left_bracket.
+ (regex_compile): Made variable SYNTAX non-const.????
+ Reformatted some code.
+ (re_compile_fastmap): Moved is_a_succeed_n's declaration to
+ inner braces.
+ Compacted some code.
+ (SET_NEWLINE_FLAG): Removed and put inline.
+ (regcomp): Made variable `syntax' non-const so can unset
+ RE_ANCHOR_NOT_NEWLINE syntax bit if cflag RE_NEWLINE is set.
+ If cflag RE_NEWLINE is set, set the RE_HAT_LISTS_NOT_NEWLINE
+ syntax bit and unset RE_ANCHOR_NOT_NEWLINE one of `syntax'.
+
+Wed Feb 20 16:33:38 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NO_CONSECUTIVE_REPEATS): Changed name from
+ RE_NO_CONSEC_REPEATS.
+ (REG_ENESTING): Deleted this POSIX return value, as the stack
+ is now unbounded.
+ (struct re_pattern_buffer): Changed some comments.
+ (re_compile_pattern): Changed a comment.
+ Deleted check on stack upper bound and corresponding error.
+ Now when there's no interval contents and it's the end of the
+ pattern, go to unmatched_left_curly_brace instead of end_of_pattern.
+ Removed nesting_too_deep error, as the stack is now unbounded.
+ (regcomp): Removed REG_ENESTING case, as the stack is now unbounded.
+ (regerror): Removed REG_ENESTING case, as the stack is now unbounded.
+
+ * regex.c (MAX_STACK_SIZE): Deleted because don't need upper
+ bound on array indexed with an unsigned number.
+
+Sun Feb 17 15:50:24 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Changed and added some comments.
+
+ * regex.c (init_syntax_once): Made `_' a word character.
+ (re_compile_pattern): Added a comment.
+ (re_match_2): Redid header comment.
+ (regexec): With header comment about PMATCH, corrected and
+ removed details found regex.h, adding a reference.
+
+Fri Feb 15 09:21:31 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (DO_RANGE): Removed argument parentheses.
+ Now get untranslated range start and end characters and set
+ list bits for the translated (if at all) versions of them and
+ all characters between them.
+ (re_match_2): Now use regs->num_regs instead of num_regs_wanted
+ wherever possible.
+ (regcomp): Now build case-fold translate table using isupper
+ and tolower facilities so will work on foreign language characters.
+
+Sat Feb 9 16:40:03 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_HAT_LISTS_NOT_NEWLINE): Changed syntax bit name
+ from RE_LISTS_NOT_NEWLINE as it only affects nonmatching lists.
+ Changed all references to the match-beginning-of-string
+ operator to match-beginning-of-line operator, as this is what
+ it does.
+ (RE_NO_CONSEC_REPEATS): Added this syntax bit.
+ (RE_SYNTAX_POSIX_BASIC): Added above bit to this.
+ (REG_PREMATURE_END): Changed name to REG_EEND.
+ (REG_EXCESS_NESTING): Changed name to REG_ENESTING.
+ (REG_TOO_BIG): Changed name to REG_ESIZE.
+ (REG_INVALID_PREV_RE): Deleted this return POSIX value.
+ Added and changed some comments.
+
+ * regex.c (re_compile_pattern): Now sets the pattern buffer's
+ `return_default_num_regs' field.
+ (typedef struct stack_element, stack_type, INIT_STACK_SIZE,
+ MAX_STACK_SIZE, STACK_EMPTY, STACK_FULL): Added for regex_compile.
+ (INIT_BUF_SIZE): Changed value from 28 to 32.
+ (BUF_PUSH): Changed name from BUFPUSH.
+ (MAX_BUF_SIZE): Added so could use in many places.
+ (IS_CHAR_CLASS_STRING): Replaced is_char_class with this.
+ (regex_compile): Added a stack which could grow dynamically
+ and which has struct elements.
+ Go back to initializing `zero_times_ok' and `many_time_ok' to
+ 0 and |=ing them inside the loop.
+ Now disallow consecutive repetition operators if the syntax
+ bit RE_NO_CONSEC_REPEATS is set.
+ Now detect trailing backslash when the compiler is expecting a
+ `?' or a `+'.
+ Changed calls to GET_BUFFER_SPACE which asked for 6 to ask for
+ 3, as that's all they needed.
+ Now check for trailing backslash inside lists.
+ Now disallow an empty alternative right before an end-of-line
+ operator.
+ Now get buffer space before leaving space for a fixup jump.
+ Now check if at pattern end when at open-interval operator.
+ Added some comments.
+ Now check if non-interval repetition operators follow an
+ interval one if the syntax bit RE_NO_CONSEC_REPEATS is set.
+ Now only check if what precedes an interval repetition
+ operator isn't a regular expression which matches one
+ character if the syntax bit RE_NO_CONSEC_REPEATS is set.
+ Now return "Unmatched [ or [^" instead of "Unmatched [".
+ (is_in_stack): Added to check if a given register number is in
+ the stack.
+ (re_match_2): If initial variable allocations fail, return -2,
+ instead of -1.
+ Now set reg's `num_regs' field when allocating regs.
+ Now before allocating them, free regs->start and end if they
+ aren't NULL and return -2 if either allocation fails.
+ Now use regs->num_regs instead of num_regs_wanted to control
+ regs loops.
+ Now increment past the newline when matching it with an
+ end-of-line operator.
+ (recomp): Added to the header comment.
+ Now return REG_ESUBREG if regex_compile returns "Unmatched [
+ or [^" instead of doing so if it returns "Unmatched [".
+ Now return REG_BADRPT if in addition to returning "Missing
+ preceding regular expression", regex_compile returns "Invalid
+ preceding regular expression".
+ Now return new return value names (see regex.h changes).
+ (regexec): Added to header comment.
+ Initialize regs structure.
+ Now match whole string.
+ Now always free regs.start and regs.end instead of just when
+ the string matched.
+ (regerror): Now return "Regex error: Unmatched [ or [^.\n"
+ instead of "Regex error: Unmatched [.\n".
+ Now return "Regex error: Preceding regular expression either
+ missing or not simple.\n" instead of "Regex error: Missing
+ preceding regular expression.\n".
+ Removed REG_INVALID_PREV_RE case (it got subsumed into the
+ REG_BADRPT case).
+
+Thu Jan 17 09:52:35 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Changed a comment.
+
+ * regex.c: Changed and added large header comments.
+ (re_compile_pattern): Now if detect that `laststart' for an
+ interval points to a byte code for a regular expression which
+ matches more than one character, make it an internal error.
+ (regerror): Return error message, don't print it.
+
+Tue Jan 15 15:32:49 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (regcomp return codes): Added GNU ones.
+ Updated some comments.
+
+ * regex.c (DO_RANGE): Changed `obscure_syntax' to `syntax'.
+ (regex_compile): Added `following_left_brace' to keep track of
+ where pseudo interval following a valid interval starts.
+ Changed some instances that returned "Invalid regular
+ expression" to instead return error strings coinciding with
+ POSIX error codes.
+ Changed some comments.
+ Now consider only things between `[:' and `:]' to be possible
+ character class names.
+ Now a character class expression can't end a pattern; at
+ least a `]' must close the list.
+ Now if the syntax bit RE_NO_BK_CURLY_BRACES is set, then a
+ valid interval must be followed by yet another to get an error
+ for preceding an interval (in this case, the second one) with
+ a regular expression that matches more than one character.
+ Now if what follows a valid interval begins with a open
+ interval operator but doesn't begin a valid interval, then set
+ following_left_bracket to it, put it in C and go to
+ normal_char label.
+ Added some comments.
+ Return "Invalid character class name" instead of "Invalid
+ character class".
+ (regerror): Return messages for all POSIX error codes except
+ REG_ECOLLATE and REG_NEWLINE, along with all GNU error codes.
+ Added `break's after all cases.
+ (main): Call re_set_syntax instead of setting `obscure_syntax'
+ directly.
+
+Sat Jan 12 13:37:59 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (Copyright): Updated date.
+ (#include <sys/types.h>): Include unconditionally.
+ (RE_CANNOT_MATCH_NEWLINE): Deleted this syntax bit.
+ (RE_SYNTAX_POSIX_BASIC, RE_SYNTAX_POSIX_EXTENDED): Removed
+ setting the RE_ANCHOR_NOT_NEWLINE syntax bit from these.
+ Changed and added some comments.
+ (struct re_pattern_buffer): Changed some flags from chars to bits.
+ Added field `syntax'; holds which syntax pattern was compiled with.
+ Added bit flag `return_default_num_regs'.
+ (externs for GNU and Berkeley UNIX routines): Added `const's to
+ parameter types to be compatible with POSIX.
+ (#define const): Added to support old C compilers.
+
+ * regex.c (Copyright): Updated date.
+ (enum regexpcode): Deleted `newline'.
+ (regex_compile): Renamed re_compile_pattern to this, added a
+ syntax parameter so it can set the pattern buffer's `syntax'
+ field.
+ Made `pattern', and `size' `const's so could pass to POSIX
+ interface routines; also made `const' whatever interval
+ variables had to be to make this work.
+ Changed references to `obscure_syntax' to new parameter `syntax'.
+ Deleted putting `newline' in buffer when see `\n'.
+ Consider invalid character classes which have nothing wrong
+ except the character class name; if so, return character-class error.
+ (is_char_class): Added routine for regex_compile.
+ (re_compile_pattern): added a new one which calls
+ regex_compile with `obscure_syntax' as the actual parameter
+ for the formal `syntax'.
+ Gave this the old routine's header comments.
+ Made `pattern', and `size' `const's so could use POSIX interface
+ routine parameters.
+ (re_search, re_search_2, re_match, re_match_2): Changed
+ `pbufp' to `bufp'.
+ (re_search_2, re_match_2): Changed `mstop' to `stop'.
+ (re_search, re_search_2): Made all parameters except `regs'
+ `const's so could use POSIX interface routines parameters.
+ (re_search_2): Added private copies of `const' parameters so
+ could change their values.
+ (re_match_2): Made all parameters except `regs' `const's so
+ could use POSIX interface routines parameters.
+ Changed `size1' and `size2' parameters to `size1_arg' and
+ `size2_arg' and so could change; added local `size1' and
+ `size2' and set to these.
+ Added some comments.
+ Deleted `newline' case.
+ `begline' can also possibly match if `d' contains a newline;
+ if it does, we have to increment d to point past the newline.
+ Replaced references to `obscure_syntax' with `bufp->syntax'.
+ (re_comp, re_exec): Made parameter `s' a `const' so could use POSIX
+ interface routines parameters.
+ Now call regex_compile, passing `obscure_syntax' via the
+ `syntax' parameter.
+ (re_exec): Made local `len' a `const' so could pass to re_search.
+ (regcomp): Added header comment.
+ Added local `syntax' to set and pass to regex_compile rather
+ than setting global `obscure_syntax' and passing it.
+ Call regex_compile with its `syntax' parameter rather than
+ re_compile_pattern.
+ Return REG_ECTYPE if character-class error.
+ (regexec): Don't initialize `regs' to anything.
+ Made `private_preg' a nonpointer so could set to what the
+ constant `preg' points.
+ Initialize `private_preg's `return_default_num_regs' field to
+ zero because want to return `nmatch' registers, not however
+ many there are subexpressions in the pattern.
+ Also test if `nmatch' > 0 to see if should pass re_match `regs'.
+
+Tue Jan 8 15:57:17 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (struct re_pattern_buffer): Reworded comment.
+
+ * regex.c (EXTEND_BUFFER): Also reset beg_interval.
+ (re_search_2): Return val if val = -2.
+ (NUM_REG_ITEMS): Listed items in comment.
+ (NUM_OTHER_ITEMS): Defined this for using in > 1 definition.
+ (MAX_NUM_FAILURE_ITEMS): Replaced `+ 2' with NUM_OTHER_ITEMS.
+ (NUM_FAILURE_ITEMS): As with definition above and added to
+ comment.
+ (PUSH_FAILURE_POINT): Replaced `* 2's with `<< 1's.
+ (re_match_2): Test with equality with 1 to see pbufp->bol and
+ pbufp->eol are set.
+
+Fri Jan 4 15:07:22 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (struct re_pattern_buffer): Reordered some fields.
+ Updated some comments.
+ Added not_bol and not_eol fields.
+ (extern regcomp, regexec, regerror): Added return types.
+ (extern regfree): Added `extern'.
+
+ * regex.c (min): Deleted unused macro.
+ (re_match_2): Compacted some code.
+ Removed call to macro `min' from `for' loop.
+ Fixed so unused registers get filled with -1's.
+ Fail if the pattern buffer's `not_bol' field is set and
+ encounter a `begline'.
+ Fail if the pattern buffer's `not_eol' field is set and
+ encounter a `endline'.
+ Deleted redundant check for empty stack in fail case.
+ Don't free pattern buffer's components in re_comp.
+ (regexec): Initialize variable regs.
+ Added `private_preg' pattern buffer so could set `not_bol' and
+ `not_eol' fields and hand to re_match.
+ Deleted naive attempt to detect anchors.
+ Set private pattern buffer's `not_bol' and `not_eol' fields
+ according to eflags value.
+ `nmatch' must also be > 0 for us to bother allocating
+ registers to send to re_match and filling pmatch
+ with their results after the call to re_match.
+ Send private pattern buffer instead of argument to re_match.
+ If use the registers, always free them and then set them to NULL.
+ (regerror): Added this Posix routine.
+ (regfree): Added this Posix routine.
+
+Tue Jan 1 15:02:45 1991 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NREGS): Deleted this definition, as now the user
+ can choose how many registers to have.
+ (REG_NOTBOL, REG_NOTEOL): Defined these Posix eflag bits.
+ (REG_NOMATCH, REG_BADPAT, REG_ECOLLATE, REG_ECTYPE,
+ REG_EESCAPE, REG_ESUBREG, REG_EBRACK, REG_EPAREN, REG_EBRACE,
+ REG_BADBR, REG_ERANGE, REG_ESPACE, REG_BADRPT, REG_ENEWLINE):
+ Defined these return values for Posix's regcomp and regexec.
+ Updated some comments.
+ (struct re_pattern_buffer): Now typedef this as regex_t
+ instead of the other way around.
+ (struct re_registers): Added num_regs field. Made start and
+ end fields pointers to char instead of fixed size arrays.
+ (regmatch_t): Added this Posix register type.
+ (regcomp, regexec, regerror, regfree): Added externs for these
+ Posix routines.
+
+ * regex.c (enum boolean): Typedefed this.
+ (re_pattern_buffer): Reformatted some comments.
+ (re_compile_pattern): Updated some comments.
+ Always push start_memory and its attendant number whenever
+ encounter a group, not just when its number is less than the
+ previous maximum number of registers; same for stop_memory.
+ Get 4 bytes of buffer space instead of 2 when pushing a
+ set_number_at.
+ (can_match_nothing): Added this to elaborate on and replace
+ code in re_match_2.
+ (reg_info_type): Made can_match_nothing field a bit instead of int.
+ (MIN): Added for re_match_2.
+ (re_match_2 macros): Changed all `for' loops which used
+ RE_NREGS to now use num_internal_regs as upper bounds.
+ (MAX_NUM_FAILURE_ITEMS): Use num_internal_regs instead of RE_NREGS.
+ (POP_FAILURE_POINT): Added check for empty stack.
+ (FREE_VARIABLES): Added this to free (and set to NULL)
+ variables allocated in re_match_2.
+ (re_match_2): Rearranged parameters to be in order.
+ Added variables num_regs_wanted (how many registers the user wants)
+ and num_internal_regs (how many groups there are).
+ Allocated initial_stack, regstart, regend, old_regstart,
+ old_regend, reginfo, best_regstart, and best_regend---all
+ which used to be fixed size arrays. Free them all and return
+ -1 if any fail.
+ Free above variables if starting position pos isn't valid.
+ Changed all `for' loops which used RE_NREGS to now use
+ num_internal_regs as upper bounds---except for the loops which
+ fill regs; then use num_regs_wanted.
+ Allocate regs if the user has passed it and wants more than 0
+ registers filled.
+ Set regs->start[i] and regs->end[i] to -1 if either
+ regstart[i] or regend[i] equals -1, not just the first.
+ Free allocated variables before returning.
+ Updated some comments.
+ (regcomp): Return REG_ESPACE, REG_BADPAT, REG_EPAREN when
+ appropriate.
+ Free translate array.
+ (regexec): Added this Posix interface routine.
+
+Mon Dec 24 14:21:13 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: If _POSIX_SOURCE is defined then #include <sys/types.h>.
+ Added syntax bit RE_CANNOT_MATCH_NEWLINE.
+ Defined Posix cflags: REG_EXTENDED, REG_NEWLINE, REG_ICASE, and
+ REG_NOSUB.
+ Added fields re_nsub and no_sub to struct re_pattern_buffer.
+ Typedefed regex_t to be `struct re_pattern_buffer'.
+
+ * regex.c (CHAR_SET_SIZE): Defined this to be 256 and replaced
+ incidences of this value with this constant.
+ (re_compile_pattern): Added switch case for `\n' and put
+ `newline' into the pattern buffer when encounter this.
+ Increment the pattern_buffer's `re_nsub' field whenever open a
+ group.
+ (re_match_2): Match a newline with `newline'---provided the
+ syntax bit RE_CANNOT_MATCH_NEWLINE isn't set.
+ (regcomp): Added this Posix interface routine.
+ (enum test_type): Added interface_test tag.
+ (main): Added Posix interface test.
+
+Tue Dec 18 12:58:12 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (struct re_pattern_buffer): reformatted so would fit
+ in texinfo documentation.
+
+Thu Nov 29 15:49:16 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NO_EMPTY_ALTS): Added this bit.
+ (RE_SYNTAX_POSIX_EXTENDED): Added above bit.
+
+ * regex.c (re_compile_pattern): Disallow empty alternatives only
+ when RE_NO_EMPTY_ALTS is set, not when RE_CONTEXTUAL_INVALID_OPS is.
+ Changed RE_NO_BK_CURLY_BRACES to RE_NO_BK_PARENS when testing
+ for empty groups at label handle_open.
+ At label handle_bar: disallow empty alternatives if RE_NO_EMPTY_ALTS
+ is set.
+ Rewrote some comments.
+
+ (re_compile_fastmap): cleaned up code.
+
+ (re_search_2): Rewrote comment.
+
+ (struct register_info): Added field `inner_groups'; it records
+ which groups are inside of the current one.
+ Added field can_match_nothing; it's set if the current group
+ can match nothing.
+ Added field ever_match_something; it's set if current group
+ ever matched something.
+
+ (INNER_GROUPS): Added macro to access inner_groups field of
+ struct register_info.
+
+ (CAN_MATCH_NOTHING): Added macro to access can_match_nothing
+ field of struct register_info.
+
+ (EVER_MATCHED_SOMETHING): Added macro to access
+ ever_matched_something field of struct register_info.
+
+ (NOTE_INNER_GROUP): Defined macro to record that a given group
+ is inside of all currently active groups.
+
+ (re_match_2): Added variables *p1 and mcnt2 (multipurpose).
+ Added old_regstart and old_regend arrays to hold previous
+ register values if they need be restored.
+ Initialize added fields and variables.
+ case start_memory: Find out if the group can match nothing.
+ Save previous register values in old_restart and old_regend.
+ Record that current group is inside of all currently active
+ groups.
+ If the group is inside a loop and it ever matched anything,
+ restore its registers to values before the last failed match.
+ Restore the registers for the inner groups, too.
+ case duplicate: Can back reference to a group that never
+ matched if it can match nothing.
+
+Thu Nov 29 11:12:54 1990 Karl Berry (karl at hayley)
+
+ * regex.c (bcopy, ...): define these if either _POSIX_SOURCE or
+ STDC_HEADERS is defined; same for including <stdlib.h>.
+
+Sat Oct 6 16:04:55 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (struct re_pattern_buffer): Changed field comments.
+
+ * regex.c (re_compile_pattern): Allow a `$' to precede an
+ alternation operator (`|' or `\|').
+ Disallow `^' and/or `$' in empty groups if the syntax bit
+ RE_NO_EMPTY_GROUPS is set.
+ Wait until have parsed a valid `\{...\}' interval expression
+ before testing RE_CONTEXTUAL_INVALID_OPS to see if it's
+ invalidated by that.
+ Don't use RE_NO_BK_CURLY_BRACES to test whether or not a validly
+ parsed interval expression is invalid if it has no preceding re;
+ rather, use RE_CONTEXTUAL_INVALID_OPS.
+ If an interval parses, but there is no preceding regular
+ expression, yet the syntax bit RE_CONTEXTUAL_INDEP_OPS is set,
+ then that interval can match the empty regular expression; if
+ the bit isn't set, then the characters in the interval
+ expression are parsed as themselves (sans the backslashes).
+ In unfetch_interval case: Moved PATFETCH to above the test for
+ RE_NO_BK_CURLY_BRACES being set, which would force a goto
+ normal_backslash; the code at both normal_backsl and normal_char
+ expect a character in `c.'
+
+Sun Sep 30 11:13:48 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Changed some comments to use the terms used in the
+ documentation.
+ (RE_CONTEXTUAL_INDEP_OPS): Changed name from `RE_CONTEXT_INDEP_OPS'.
+ (RE_LISTS_NOT_NEWLINE): Changed name from `RE_HAT_NOT_NEWLINE.'
+ (RE_ANCHOR_NOT_NEWLINE): Added this syntax bit.
+ (RE_NO_EMPTY_GROUPS): Added this syntax bit.
+ (RE_NO_HYPHEN_RANGE_END): Deleted this syntax bit.
+ (RE_SYNTAX_...): Reformatted.
+ (RE_SYNTAX_POSIX_BASIC, RE_SYNTAX_EXTENDED): Added syntax bits
+ RE_ANCHOR_NOT_NEWLINE and RE_NO_EMPTY_GROUPS, and deleted
+ RE_NO_HYPHEN_RANGE_END.
+ (RE_SYNTAX_POSIX_EXTENDED): Added syntax bit RE_DOT_NOT_NULL.
+
+ * regex.c (bcopy, bcmp, bzero): Define if _POSIX_SOURCE is defined.
+ (_POSIX_SOURCE): ifdef this, #include <stdlib.h>
+ (#ifdef emacs): Changed comment of the #endif for the its #else
+ clause to be `not emacs', not `emacs.'
+ (no_pop_jump): Changed name from `jump'.
+ (pop_failure_jump): Changed name from `finalize_jump.'
+ (maybe_pop_failure_jump): Changed name from `maybe_finalize_jump'.
+ (no_pop_jump_n): Changed name from `jump_n.'
+ (EXTEND_BUFFER): Use shift instead of multiplication to double
+ buf->allocated.
+ (DO_RANGE, recompile_pattern): Added macro to set the list bits
+ for a range.
+ (re_compile_pattern): Fixed grammar problems in some comments.
+ Checked that RE_NO_BK_VBAR is set to make `$' valid before a `|'
+ and not set to make it valid before a `\|'.
+ Checked that RE_NO_BK_PARENS is set to make `$' valid before a ')'
+ and not set to make it valid before a `\)'.
+ Disallow ranges starting with `-', unless the range is the
+ first item in a list, rather than disallowing ranges which end
+ with `-'.
+ Disallow empty groups if the syntax bit RE_NO_EMPTY_GROUPS is set.
+ Disallow nothing preceding `{' and `\{' if they represent the
+ open-interval operator and RE_CONTEXTUAL_INVALID_OPS is set.
+ (register_info_type): typedef-ed this using `struct register_info.'
+ (SET_REGS_MATCHED): Compacted the code.
+ (re_match_2): Made it fail if back reference a group which we've
+ never matched.
+ Made `^' not match a newline if the syntax bit
+ RE_ANCHOR_NOT_NEWLINE is set.
+ (really_fail): Added this label so could force a final fail that
+ would not try to use the failure stack to recover.
+
+Sat Aug 25 14:23:01 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_CONTEXTUAL_OPS): Changed name from RE_CONTEXT_OPS.
+ (global): Rewrote comments and rebroke some syntax #define lines.
+
+ * regex.c (isgraph): Added definition for sequents.
+ (global): Now refer to character set lists as ``lists.''
+ Rewrote comments containing ``\('' or ``\)'' to now refer to
+ ``groups.''
+ (RE_CONTEXTUAL_OPS): Changed name from RE_CONTEXT_OPS.
+
+ (re_compile_pattern): Expanded header comment.
+
+Sun Jul 15 14:50:25 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_CONTEX_INDEP_OPS): the comment's sense got turned
+ around when we changed how it read; changed it to be correct.
+
+Sat Jul 14 16:38:06 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NO_EMPTY_BK_REF): changed name to
+ RE_NO_MISSING_BK_REF, as this describes it better.
+
+ * regex.c (re_compile_pattern): changed RE_NO_EMPTY_BK_REF
+ to RE_NO_MISSING_BK_REF, as above.
+
+Thu Jul 12 11:45:05 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h (RE_NO_EMPTY_BRACKETS): removed this syntax bit, as
+ bracket expressions should *never* be empty regardless of the
+ syntax. Removes this bit from RE_SYNTAX_POSIX_BASIC and
+ RE_SYNTAX_POSIX_EXTENDED.
+
+ * regex.c (SET_LIST_BIT): in the comment, now refer to character
+ sets as (non)matching sets, as bracket expressions can now match
+ other things in addition to characters.
+ (re_compile_pattern): refer to groups as such instead of `\(...\)'
+ or somesuch, because groups can now be enclosed in either plain
+ parens or backslashed ones, depending on the syntax.
+ In the '[' case, added a boolean just_had_a_char_class to detect
+ whether or not a character class begins a range (which is invalid).
+ Restore way of breaking out of a bracket expression to original way.
+ Add way to detect a range if the last thing in a bracket
+ expression was a character class.
+ Took out check for c != ']' at the end of a character class in
+ the else clause, as it had already been checked in the if part
+ that also checked the validity of the string.
+ Set or clear just_had_a_char_class as appropriate.
+ Added some comments. Changed references to character sets to
+ ``(non)matching lists.''
+
+Sun Jul 1 12:11:29 1990 Karl Berry (karl at hayley)
+
+ * regex.h (BYTEWIDTH): moved back to regex.c.
+
+ * regex.h (re_compile_fastmap): removed declaration; this
+ shouldn't be advertised.
+
+Mon May 28 15:27:53 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (ifndef Sword): Made comments more specific.
+ (global): include <stdio.h> so can write fatal messages on
+ standard error. Replaced calls to assert with fprintfs to
+ stderr and exit (1)'s.
+ (PREFETCH): Reformatted to make more readable.
+ (AT_STRINGS_BEG): Defined to test if we're at the beginning of
+ the virtual concatenation of string1 and string2.
+ (AT_STRINGS_END): Defined to test if at the end of the virtual
+ concatenation of string1 and string2.
+ (AT_WORD_BOUNDARY): Defined to test if are at a word boundary.
+ (IS_A_LETTER(d)): Defined to test if the contents of the pointer D
+ is a letter.
+ (re_match_2): Rewrote the wordbound, notwordbound, wordbeg, wordend,
+ begbuf, and endbuf cases in terms of the above four new macros.
+ Called SET_REGS_MATCHED in the matchsyntax, matchnotsyntax,
+ wordchar, and notwordchar cases.
+
+Mon May 14 14:49:13 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (re_search_2): Fixed RANGE to not ever take STARTPOS
+ outside of virtual concatenation of STRING1 and STRING2.
+ Updated header comment as to this.
+ (re_match_2): Clarified comment about MSTOP in header.
+
+Sat May 12 15:39:00 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (re_search_2): Checked for out-of-range STARTPOS.
+ Added comments.
+ When searching backwards, not only get the character with which
+ to compare to the fastmap from string2 if the starting position
+ >= size1, but also if size1 is zero; this is so won't get a
+ segmentation fault if string1 is null.
+ Reformatted code at label advance.
+
+Thu Apr 12 20:26:21 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Added #pragma once and #ifdef...endif __REGEXP_LIBRARY.
+ (RE_EXACTN_VALUE): Added for search.c to use.
+ Reworded some comments.
+
+ regex.c: Punctuated some comments correctly.
+ (NULL): Removed this.
+ (RE_EXACTN_VALUE): Added for search.c to use.
+ (<ctype.h>): Moved this include to top of file.
+ (<assert.h>): Added this include.
+ (struct regexpcode): Assigned 0 to unused and 1 to exactn
+ because of RE_EXACTN_VALUE.
+ Added comment.
+ (various macros): Lined up backslashes near end of line.
+ (insert_jump): Cleaned up the header comment.
+ (re_search): Corrected the header comment.
+ (re_search_2): Cleaned up and completed the header comment.
+ (re_max_failures): Updated comment.
+ (struct register_info): Constructed as bits so as to save space
+ on the stack when pushing register information.
+ (IS_ACTIVE): Macro for struct register_info.
+ (MATCHED_SOMETHING): Macro for struct register_info.
+ (NUM_REG_ITEMS): How many register information items for each
+ register we have to push on the stack at each failure.
+ (MAX_NUM_FAILURE_ITEMS): If push all the registers on failure,
+ this is how many items we push on the stack.
+ (PUSH_FAILURE_POINT): Now pushes whether or not the register is
+ currently active, and whether or not it matched something.
+ Checks that there's enough space allocated to accomodate all the
+ items we currently want to push. (Before, a test for an empty
+ stack sufficed because we always pushed and popped the same
+ number of items).
+ Replaced ``2'' with MAX_NUM_FAILURE_POINTS when ``2'' refers
+ to how many things get pushed on the stack each time.
+ When copy the stack into the newly allocated storage, now only copy
+ the area in use.
+ Clarified comment.
+ (POP_FAILURE_POINT): Defined to use in places where put number
+ of registers on the stack into a variable before using it to
+ decrement the stack, so as to not confuse the compiler.
+ (IS_IN_FIRST_STRING): Defined to check if a pointer points into
+ the first string.
+ (SET_REGS_MATCHED): Changed to use the struct register_info
+ bits; also set the matched-something bit to false if the
+ register isn't currently active. (This is a redundant setting.)
+ (re_match_2): Cleaned up and completed the header comment.
+ Updated the failure stack comment.
+ Replaced the ``2'' with MAX_NUM_FAILURE_ITEMS in the static
+ allocation of initial_stack, because now more than two (now up
+ to MAX_FAILURE_ITEMS) items get pushed on the failure stack each
+ time.
+ Ditto for stackb.
+ Trashed restart_seg1, regend_seg1, best_regstart_seg1, and
+ best_regend_seg1 because they could have erroneous information
+ in them, such as when matching ``a'' (in string1) and ``ab'' (in
+ string2) with ``(a)*ab''; before using IS_IN_FIRST_STRING to see
+ whether or not the register starts or ends in string1,
+ regstart[1] pointed past the end of string1, yet regstart_seg1
+ was 0!
+ Added variable reg_info of type struct register_info to keep
+ track of currently active registers and whether or not they
+ currently match anything.
+ Commented best_regs_set.
+ Trashed reg_active and reg_matched_something and put the
+ information they held into reg_info; saves space on the stack.
+ Replaced NULL with '\000'.
+ In begline case, compacted the code.
+ Used assert to exit if had an internal error.
+ In begbuf case, because now force the string we're working on
+ into string2 if there aren't two strings, now allow d == string2
+ if there is no string1 (and the check for that is size1 == 0!);
+ also now succeeds if there aren't any strings at all.
+ (main, ifdef canned): Put test type into a variable so could
+ change it while debugging.
+
+Sat Mar 24 12:24:13 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (GET_UNSIGNED_NUMBER): Deleted references to num_fetches.
+ (re_compile_pattern): Deleted num_fetches because could keep
+ track of the number of fetches done by saving a pointer into the
+ pattern.
+ Added variable beg_interval to be used as a pointer, as above.
+ Assert that beg_interval points to something when it's used as above.
+ Initialize succeed_n's to lower_bound because re_compile_fastmap
+ needs to know it.
+ (re_compile_fastmap): Deleted unnecessary variable is_a_jump_n.
+ Added comment.
+ (re_match_2): Put number of registers on the stack into a
+ variable before using it to decrement the stack, so as to not
+ confuse the compiler.
+ Updated comments.
+ Used error routine instead of printf and exit.
+ In exactn case, restored longer code from ``original'' regex.c
+ which doesn't test translate inside a loop.
+
+ * regex.h: Moved #define NULL and the enum regexpcode definition
+ and to regex.c. Changed some comments.
+
+ regex.c (global): Updated comments about compiling and for the
+ re_compile_pattern jump routines.
+ Added #define NULL and the enum regexpcode definition (from
+ regex.h).
+ (enum regexpcode): Added set_number_at to reset the n's of
+ succeed_n's and jump_n's.
+ (re_set_syntax): Updated its comment.
+ (re_compile_pattern): Moved its heading comment to after its macros.
+ Moved its include statement to the top of the file.
+ Commented or added to comments of its macros.
+ In start_memory case: Push laststart value before adding
+ start_memory and its register number to the buffer, as they
+ might not get added.
+ Added code to put a set_number_at before each succeed_n and one
+ after each jump_n; rewrote code in what seemed a more
+ straightforward manner to put all these things in the pattern so
+ the succeed_n's would correctly jump to the set_number_at's of
+ the matching jump_n's, and so the jump_n's would correctly jump
+ to after the set_number_at's of the matching succeed_n's.
+ Initialize succeed_n n's to -1.
+ (insert_op_2): Added this to insert an operation followed by
+ two integers.
+ (re_compile_fastmap): Added set_number_at case.
+ (re_match_2): Moved heading comment to after macros.
+ Added mention of REGS to heading comment.
+ No longer turn a succeed_n with n = 0 into an on_failure_jump,
+ because n needs to be reset each time through a loop.
+ Check to see if a succeed_n's n is set by its set_number_at.
+ Added set_number_at case.
+ Updated some comments.
+ (main): Added another main to run posix tests, which is compiled
+ ifdef both test and canned. (Old main is still compiled ifdef
+ test only).
+
+Tue Mar 19 09:22:55 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.[hc]: Change all instances of the word ``legal'' to
+ ``valid'' and all instances of ``illegal'' to ``invalid.''
+
+Sun Mar 4 12:11:31 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Added syntax bit RE_NO_EMPTY_RANGES which is set if
+ an ending range point has to collate higher or equal to the
+ starting range point.
+ Added syntax bit RE_NO_HYPHEN_RANGE_END which is set if a hyphen
+ can't be an ending range point.
+ Set to two above bits in RE_SYNTAX_POSIX_BASIC and
+ RE_SYNTAX_POSIX_EXTENDED.
+
+ regex.c: (re_compile_pattern): Don't allow empty ranges if the
+ RE_NO_EMPTY_RANGES syntax bit is set.
+ Don't let a hyphen be a range end if the RE_NO_HYPHEN_RANGE_END
+ syntax bit is set.
+ (ESTACK_PUSH_2): renamed this PUSH_FAILURE_POINT and made it
+ push all the used registers on the stack, as well as the number
+ of the highest numbered register used, and (as before) the two
+ failure points.
+ (re_match_2): Fixed up comments.
+ Added arrays best_regstart[], best_regstart_seg1[], best_regend[],
+ and best_regend_seg1[] to keep track of the best match so far
+ whenever reach the end of the pattern but not the end of the
+ string, and there are still failure points on the stack with
+ which to backtrack; if so, do the saving and force a fail.
+ If reach the end of the pattern but not the end of the string,
+ but there are no more failure points to try, restore the best
+ match so far, set the registers and return.
+ Compacted some code.
+ In stop_memory case, if the subexpression we've just left is in
+ a loop, push onto the stack the loop's on_failure_jump failure
+ point along with the current pointer into the string (d).
+ In finalize_jump case, in addition to popping the failure
+ points, pop the saved registers.
+ In the fail case, restore the registers, as well as the failure
+ points.
+
+Sun Feb 18 15:08:10 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: (global): Defined a macro GET_BUFFER_SPACE which
+ makes sure you have a specified number of buffer bytes
+ allocated.
+ Redefined the macro BUFPUSH to use this.
+ Added comments.
+
+ (re_compile_pattern): Call GET_BUFFER_SPACE before storing or
+ inserting any jumps.
+
+ (re_match_2): Set d to string1 + pos and dend to end_match_1
+ only if string1 isn't null.
+ Force exit from a loop if it's around empty parentheses.
+ In stop_memory case, if found some jumps, increment p2 before
+ extracting address to which to jump. Also, don't need to know
+ how many more times can jump_n.
+ In begline case, d must equal string1 or string2, in that order,
+ only if they are not null.
+ In maybe_finalize_jump case, skip over start_memorys' and
+ stop_memorys' register numbers, too.
+
+Thu Feb 15 15:53:55 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (BUFPUSH): off by one goof in deciding whether to
+ EXTEND_BUFFER.
+
+Wed Jan 24 17:07:46 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Moved definition of NULL to here.
+ Got rid of ``In other words...'' comment.
+ Added to some comments.
+
+ regex.c: (re_compile_pattern): Tried to bulletproof some code,
+ i.e., checked if backward references (e.g., p[-1]) were within
+ the range of pattern.
+
+ (re_compile_fastmap): Fixed a bug in succeed_n part where was
+ getting the amount to jump instead of how many times to jump.
+
+ (re_search_2): Changed the name of the variable ``total'' to
+ ``total_size.''
+ Condensed some code.
+
+ (re_match_2): Moved the comment about duplicate from above the
+ start_memory case to above duplicate case.
+
+ (global): Rewrote some comments.
+ Added commandline arguments to testing.
+
+Wed Jan 17 11:47:27 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: (global): Defined a macro STORE_NUMBER which stores a
+ number into two contiguous bytes. Also defined STORE_NUMBER_AND_INCR
+ which does the same thing and then increments the pointer to the
+ storage place to point after the number.
+ Defined a macro EXTRACT_NUMBER which extracts a number from two
+ continguous bytes. Also defined EXTRACT_NUMBER_AND_INCR which
+ does the same thing and then increments the pointer to the
+ source to point to after where the number was.
+
+Tue Jan 16 12:09:19 1990 Kathy Hargreaves (kathy at hayley)
+
+ * regex.h: Incorporated rms' changes.
+ Defined RE_NO_BK_REFS syntax bit which is set when want to
+ interpret back reference patterns as literals.
+ Defined RE_NO_EMPTY_BRACKETS syntax bit which is set when want
+ empty bracket expressions to be illegal.
+ Defined RE_CONTEXTUAL_ILLEGAL_OPS syntax bit which is set when want
+ it to be illegal for *, +, ? and { to be first in an re or come
+ immediately after a | or a (, and for ^ not to appear in a
+ nonleading position and $ in a nontrailing position (outside of
+ bracket expressions, that is).
+ Defined RE_LIMITED_OPS syntax bit which is set when want +, ?
+ and | to always be literals instead of ops.
+ Fixed up the Posix syntax.
+ Changed the syntax bit comments from saying, e.g., ``0 means...''
+ to ``If this bit is set, it means...''.
+ Changed the syntax bit defines to use shifts instead of integers.
+
+ * regex.c: (global): Incorporated rms' changes.
+
+ (re_compile_pattern): Incorporated rms' changes
+ Made it illegal for a $ to appear anywhere but inside a bracket
+ expression or at the end of an re when RE_CONTEXTUAL_ILLEGAL_OPS
+ is set. Made the same hold for $ except it has to be at the
+ beginning of an re instead of the end.
+ Made the re "[]" illegal if RE_NO_EMPTY_BRACKETS is set.
+ Made it illegal for | to be first or last in an re, or immediately
+ follow another | or a (.
+ Added and embellished some comments.
+ Allowed \{ to be interpreted as a literal if RE_NO_BK_CURLY_BRACES
+ is set.
+ Made it illegal for *, +, ?, and { to appear first in an re, or
+ immediately follow a | or a ( when RE_CONTEXTUAL_ILLEGAL_OPS is set.
+ Made back references interpreted as literals if RE_NO_BK_REFS is set.
+ Made recursive intervals either illegal (if RE_NO_BK_CURLY_BRACES
+ isn't set) or interpreted as literals (if is set), if RE_INTERVALS
+ is set.
+ Made it treat +, ? and | as literals if RE_LIMITED_OPS is set.
+ Cleaned up some code.
+
+Thu Dec 21 15:31:32 1989 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: (global): Moved RE_DUP_MAX to regex.h and made it
+ equal 2^15 - 1 instead of 1000.
+ Defined NULL to be zero.
+ Moved the definition of BYTEWIDTH to regex.h.
+ Made the global variable obscure_syntax nonstatic so the tests in
+ another file could use it.
+
+ (re_compile_pattern): Defined a maximum length (CHAR_CLASS_MAX_LENGTH)
+ for character class strings (i.e., what's between the [: and the
+ :]'s).
+ Defined a macro SET_LIST_BIT(c) which sets the bit for C in a
+ character set list.
+ Took out comments that EXTEND_BUFFER clobbers C.
+ Made the string "^" match itself, if not RE_CONTEXT_IND_OPS.
+ Added character classes to bracket expressions.
+ Change the laststart pointer saved with the start of each
+ subexpression to point to start_memory instead of after the
+ following register number. This is because the subexpression
+ might be in a loop.
+ Added comments and compacted some code.
+ Made intervals only work if preceded by an re matching a single
+ character or a subexpression.
+ Made back references to nonexistent subexpressions illegal if
+ using POSIX syntax.
+ Made intervals work on the last preceding character of a
+ concatenation of characters, e.g., ab{0,} matches abbb, not abab.
+ Moved macro PREFETCH to outside the routine.
+
+ (re_compile_fastmap): Added succeed_n to work analogously to
+ on_failure_jump if n is zero and jump_n to work analogously to
+ the other backward jumps.
+
+ (re_match_2): Defined macro SET_REGS_MATCHED to set which
+ current subexpressions had matches within them.
+ Changed some comments.
+ Added reg_active and reg_matched_something arrays to keep track
+ of in which subexpressions currently have matched something.
+ Defined MATCHING_IN_FIRST_STRING and replaced ``dend == end_match_1''
+ with it to make code easier to understand.
+ Fixed so can apply * and intervals to arbitrarily nested
+ subexpressions. (Lots of previous bugs here.)
+ Changed so won't match a newline if syntax bit RE_DOT_NOT_NULL is set.
+ Made the upcase array nonstatic so the testing file could use it also.
+
+ (main.c): Moved the tests out to another file.
+
+ (tests.c): Moved all the testing stuff here.
+
+Sat Nov 18 19:30:30 1989 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: (re_compile_pattern): Defined RE_DUP_MAX, the maximum
+ number of times an interval can match a pattern.
+ Added macro GET_UNSIGNED_NUMBER (used to get below):
+ Added variables lower_bound and upper_bound for upper and lower
+ bounds of intervals.
+ Added variable num_fetches so intervals could do backtracking.
+ Added code to handle '{' and "\{" and intervals.
+ Added to comments.
+
+ (store_jump_n): (Added) Stores a jump with a number following the
+ relative address (for intervals).
+
+ (insert_jump_n): (Added) Inserts a jump_n.
+
+ (re_match_2): Defined a macro ESTACK_PUSH_2 for the error stack;
+ it checks for overflow and reallocates if necessary.
+
+ * regex.h: Added bits (RE_INTERVALS and RE_NO_BK_CURLY_BRACES)
+ to obscure syntax to indicate whether or not
+ a syntax handles intervals and recognizes either \{ and
+ \} or { and } as operators. Also added two syntaxes
+ RE_SYNTAX_POSIX_BASIC and RE_POSIX_EXTENDED and two command codes
+ to the enumeration regexpcode; they are succeed_n and jump_n.
+
+Sat Nov 18 19:30:30 1989 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c: (re_compile_pattern): Defined INIT_BUFF_SIZE to get rid
+ of repeated constants in code. Tested with value 1.
+ Renamed PATPUSH as BUFPUSH, since it pushes things onto the
+ buffer, not the pattern. Also made this macro extend the buffer
+ if it's full (so could do the following):
+ Took out code at top of loop that checks to see if buffer is going
+ to be full after 10 additions (and reallocates if necessary).
+
+ (insert_jump): Rearranged declaration lines so comments would read
+ better.
+
+ (re_match_2): Compacted exactn code and added more comments.
+
+ (main): Defined macros TEST_MATCH and MATCH_SELF to do
+ testing; took out loop so could use these instead.
+
+Tue Oct 24 20:57:18 1989 Kathy Hargreaves (kathy at hayley)
+
+ * regex.c (re_set_syntax): Gave argument `syntax' a type.
+ (store_jump, insert_jump): made them void functions.
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+version-control: never
+End:
diff --git a/gnu/lib/libregex/INSTALL b/gnu/lib/libregex/INSTALL
new file mode 100644
index 0000000..014e0f7
--- /dev/null
+++ b/gnu/lib/libregex/INSTALL
@@ -0,0 +1,117 @@
+This is a generic INSTALL file for utilities distributions.
+If this package does not come with, e.g., installable documentation or
+data files, please ignore the references to them below.
+
+To compile this package:
+
+1. Configure the package for your system. In the directory that this
+file is in, type `./configure'. 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.
+
+The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation, and
+creates the Makefile(s) (one in each subdirectory of the source
+directory). In some packages it creates a C header file containing
+system-dependent definitions. It also creates a file `config.status'
+that you can run in the future to recreate the current configuration.
+
+Running `configure' takes a minute or two. While it is running, it
+prints some messages that tell what it is doing. If you don't want to
+see the messages, run `configure' with its standard output redirected
+to `/dev/null'; for example, `./configure >/dev/null'.
+
+To compile the package in a different directory from the one
+containing the source code, 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
+`configure'. `configure' automatically checks for the source code in
+the directory that `configure' is in and in `..'. If for some reason
+`configure' is not in the source code directory that you are
+configuring, then it will report that it can't find the source code.
+In that case, run `configure' with the option `--srcdir=DIR', where
+DIR is the directory that contains the source code.
+
+By default, `make install' will install the package's files in
+/usr/local/bin, /usr/local/lib, /usr/local/man, etc. You can specify
+an installation prefix other than /usr/local by giving `configure' the
+option `--prefix=PATH'. Alternately, you can do so by giving a value
+for the `prefix' variable when you run `make', e.g.,
+ make prefix=/usr/gnu
+
+You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If
+you give `configure' the option `--exec-prefix=PATH' or set the
+`make' variable `exec_prefix' to PATH, the package will use PATH as
+the prefix for installing programs and libraries. Data files and
+documentation will still use the regular prefix. Normally, all files
+are installed using the regular prefix.
+
+Another `configure' option is useful mainly in `Makefile' rules for
+updating `config.status' and `Makefile'. The `--no-create' option
+figures out the configuration for your system and records it in
+`config.status', without actually configuring the package (creating
+`Makefile's and perhaps a configuration header file). Later, you can
+run `./config.status' to actually configure the package. You can also
+give `config.status' the `--recheck' option, which makes it re-run
+`configure' with the same arguments you used before. This option is
+useful if you change `configure'.
+
+Some packages pay attention to `--with-PACKAGE' options to `configure',
+where PACKAGE is something like `gnu-libc' or `x' (for the X Window System).
+The README should mention any --with- options that the package recognizes.
+
+`configure' ignores any other arguments that you give it.
+
+If your system requires unusual options for compilation or linking
+that `configure' doesn't know about, you can give `configure' initial
+values for some variables by setting them in the environment. In
+Bourne-compatible shells, you can do that on the command line like
+this:
+ CC='gcc -traditional' DEFS=-D_POSIX_SOURCE ./configure
+
+The `make' variables that you might want to override with environment
+variables when running `configure' are:
+
+(For these variables, any value given in the environment overrides the
+value that `configure' would choose:)
+CC C compiler program.
+ Default is `cc', or `gcc' if `gcc' is in your PATH.
+INSTALL Program to use to install files.
+ Default is `install' if you have it, `cp' otherwise.
+
+(For these variables, any value given in the environment is added to
+the value that `configure' chooses:)
+DEFS Configuration options, in the form `-Dfoo -Dbar ...'
+ Do not use this variable in packages that create a
+ configuration header file.
+LIBS Libraries to link with, in the form `-lfoo -lbar ...'
+
+If you need to do unusual things to compile the package, we encourage
+you to figure out how `configure' could check whether to do them, and
+mail diffs or instructions to the address given in the README so we
+can include them in the next release.
+
+2. Type `make' to compile the package. If you want, you can override
+the `make' variables CFLAGS and LDFLAGS like this:
+
+ make CFLAGS=-O2 LDFLAGS=-s
+
+3. If the package comes with self-tests and you want to run them,
+type `make check'. If you're not sure whether there are any, try it;
+if `make' responds with something like
+ make: *** No way to make target `check'. Stop.
+then the package does not come with self-tests.
+
+4. Type `make install' to install programs, data files, and
+documentation.
+
+5. You can remove the program binaries and object files from the
+source directory by typing `make clean'. To also remove the
+Makefile(s), the header file containing system-dependent definitions
+(if the package uses one), and `config.status' (all the files that
+`configure' created), type `make distclean'.
+
+The file `configure.in' is used as a template to create `configure' by
+a program called `autoconf'. You will only need it if you want to
+regenerate `configure' using a newer version of `autoconf'.
diff --git a/gnu/lib/libregex/Makefile b/gnu/lib/libregex/Makefile
new file mode 100644
index 0000000..1d59e0d
--- /dev/null
+++ b/gnu/lib/libregex/Makefile
@@ -0,0 +1,15 @@
+# $Header: /home/ncvs/src/gnu/lib/libregex/Makefile,v 1.17 1996/08/12 19:04:23 ache Exp $
+
+
+LIB= gnuregex
+CFLAGS+=-I${.CURDIR} -DHAVE_STRING_H=1 -DSTDC_HEADERS=1
+SRCS= regex.c
+NOMAN= noman
+
+SUBDIR+= doc
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/regex.h \
+ ${DESTDIR}/usr/include/gnuregex.h
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libregex/Makefile.gnu b/gnu/lib/libregex/Makefile.gnu
new file mode 100644
index 0000000..b8bc209
--- /dev/null
+++ b/gnu/lib/libregex/Makefile.gnu
@@ -0,0 +1,99 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile for regex.
+#
+# Copyright (C) 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+version = 0.12
+
+# You can define CPPFLAGS on the command line. Aside from system-specific
+# flags, you can define:
+# -DREGEX_MALLOC to use malloc/realloc/free instead of alloca.
+# -DDEBUG to enable the compiled pattern disassembler and execution
+# tracing; code runs substantially slower.
+# -DEXTRACT_MACROS to use the macros EXTRACT_* (as opposed to
+# the corresponding C procedures). If not -DDEBUG, the macros
+# are used.
+CPPFLAGS =
+
+# Likewise, you can override CFLAGS to optimize, use -Wall, etc.
+CFLAGS = -g
+
+# Ditto for LDFLAGS and LOADLIBES.
+LDFLAGS =
+LOADLIBES =
+
+srcdir = .
+VPATH = .
+
+CC = gcc
+DEFS = -DHAVE_STRING_H=1
+
+SHELL = /bin/sh
+
+subdirs = doc test
+
+default all:: regex.o
+.PHONY: default all
+
+regex.o: regex.c regex.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -c $<
+
+clean mostlyclean::
+ rm -f *.o
+
+distclean:: clean
+ rm -f Makefile config.status
+
+extraclean:: distclean
+ rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
+
+configure: configure.in
+ autoconf
+
+config.status: configure
+ sh configure --no-create
+
+Makefile: Makefile.in config.status
+ sh config.status
+
+makeargs = $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CC='$(CC)' \
+DEFS='$(DEFS)' LDFLAGS='$(LDFLAGS)' LOADLIBES='$(LOADLIBES)'
+
+default all install \
+mostlyclean clean distclean extraclean realclean \
+TAGS check::
+ for d in $(subdirs); do (cd $$d; $(MAKE) $(makeargs) $@); done
+.PHONY: install mostlyclean clean distclean extraclean realclean TAGS check
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+distfiles = AUTHORS ChangeLog COPYING INSTALL NEWS README \
+ *.in configure regex.c regex.h
+distdir = regex-$(version)
+distargs = version=$(version) distdir=../$(distdir)/$$d
+dist: TAGS configure
+ @echo "Version numbers in: Makefile.in, ChangeLog, NEWS,"
+ @echo " regex.c, regex.h,"
+ @echo " and doc/xregex.texi (if modified)."
+ rm -rf $(distdir)
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+ for d in $(subdirs); do (cd $$d; $(MAKE) $(distargs) dist); done
+ tar czhf $(distdir).tar.Z $(distdir)
+ rm -rf $(distdir)
+.PHONY: dist
diff --git a/gnu/lib/libregex/Makefile.in b/gnu/lib/libregex/Makefile.in
new file mode 100644
index 0000000..a21f970
--- /dev/null
+++ b/gnu/lib/libregex/Makefile.in
@@ -0,0 +1,98 @@
+# Makefile for regex.
+#
+# Copyright (C) 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+version = 0.12
+
+# You can define CPPFLAGS on the command line. Aside from system-specific
+# flags, you can define:
+# -DREGEX_MALLOC to use malloc/realloc/free instead of alloca.
+# -DDEBUG to enable the compiled pattern disassembler and execution
+# tracing; code runs substantially slower.
+# -DEXTRACT_MACROS to use the macros EXTRACT_* (as opposed to
+# the corresponding C procedures). If not -DDEBUG, the macros
+# are used.
+CPPFLAGS =
+
+# Likewise, you can override CFLAGS to optimize, use -Wall, etc.
+CFLAGS = -g
+
+# Ditto for LDFLAGS and LOADLIBES.
+LDFLAGS =
+LOADLIBES =
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+DEFS = @DEFS@
+
+SHELL = /bin/sh
+
+subdirs = doc test
+
+default all:: regex.o
+.PHONY: default all
+
+regex.o: regex.c regex.h
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) -c $<
+
+clean mostlyclean::
+ rm -f *.o
+
+distclean:: clean
+ rm -f Makefile config.status
+
+extraclean:: distclean
+ rm -f patch* *~* *\#* *.orig *.rej *.bak core a.out
+
+configure: configure.in
+ autoconf
+
+config.status: configure
+ sh configure --no-create
+
+Makefile: Makefile.in config.status
+ sh config.status
+
+makeargs = $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CC='$(CC)' \
+DEFS='$(DEFS)' LDFLAGS='$(LDFLAGS)' LOADLIBES='$(LOADLIBES)'
+
+default all install \
+mostlyclean clean distclean extraclean realclean \
+TAGS check::
+ for d in $(subdirs); do (cd $$d; $(MAKE) $(makeargs) $@); done
+.PHONY: install mostlyclean clean distclean extraclean realclean TAGS check
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+distfiles = AUTHORS ChangeLog COPYING INSTALL NEWS README \
+ *.in configure regex.c regex.h
+distdir = regex-$(version)
+distargs = version=$(version) distdir=../$(distdir)/$$d
+dist: TAGS configure
+ @echo "Version numbers in: Makefile.in, ChangeLog, NEWS,"
+ @echo " regex.c, regex.h,"
+ @echo " and doc/xregex.texi (if modified)."
+ rm -rf $(distdir)
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+ for d in $(subdirs); do (cd $$d; $(MAKE) $(distargs) dist); done
+ tar czhf $(distdir).tar.Z $(distdir)
+ rm -rf $(distdir)
+.PHONY: dist
diff --git a/gnu/lib/libregex/NEWS b/gnu/lib/libregex/NEWS
new file mode 100644
index 0000000..b3a899b
--- /dev/null
+++ b/gnu/lib/libregex/NEWS
@@ -0,0 +1,62 @@
+Version 0.12
+
+* regex.c does not #define bcmp/bcopy/bzero if they already are.
+
+* regex.h does not redefine `const' if it is already defined, even if
+ __STDC__ is not defined.
+
+* RE_SYNTAX_ED added (same as POSIX BRE's).
+
+* The following bugs have been fixed, among others:
+ * The pattern \w+ doesn't infinite loop.
+ * The pattern ".+\n" is compiled correctly.
+ * Expressions with more than MAX_REGNUM groups are compiled correctly.
+
+* Patterns that end in a repetition operator (e.g., `*') match
+ slightly faster if no looping is actually necessary.
+
+Version 0.11 (17 Sep 92)
+
+* Back-references to nonexistent subexpressions, as in the r.e. `abc\1',
+ are always invalid. Previously, they could match the literal digit,
+ e.g., the stated r.e. might have matched `abc1'.
+
+* Empty subexpressions are always valid (POSIX leaves this undefined).
+
+* Simplified rules for ^ and $ being anchors.
+
+* One minor speedup (rewriting the C procedure `pop_failure_point' as a
+ macro again).
+
+* Bug fixes involving:
+ - Declarations in regex.h and non-ANSI compilers.
+ - Bracket expressions with characters between 0x80-0xff.
+ - Memory leak in re_match_2 on systems requiring `alloca (0)' to
+ free alloca'd storage.
+
+* Test and documentation files moved into subdirectories.
+
+Version 0.10 (9 Sep 92)
+
+* `obscure_syntax' is now called `re_default_syntax'.
+
+* `re_comp's return type is no longer `const', for compatibility with BSD.
+
+* POSIX syntaxes now include as much functionality as possible
+ (consistent with the standard).
+
+* Compilation conditionals normalized to what the rest of GNU is
+ migrating towards these days.
+
+* Bug fixes involving:
+ - Ranges with characters between 0x80 and 0xff, e.g., [\001-\377].
+ - `re_compile_fastmap' and the sequence `.*\n'.
+ - Intervals with exact counts, e.g., a{5}.
+
+* Changed distribution to use a standard Makefile, install the info
+ files, use a configure script, etc.
+
+Version 0.9
+
+* The longest match was not always chosen: `a*|ab' didn't match `aab'.
+
diff --git a/gnu/lib/libregex/README b/gnu/lib/libregex/README
new file mode 100644
index 0000000..918e1a0
--- /dev/null
+++ b/gnu/lib/libregex/README
@@ -0,0 +1,60 @@
+This directory contains the GNU regex library. It is compliant with
+POSIX.2, except for internationalization features.
+
+See the file NEWS for a list of major changes in the current release.
+
+See the file INSTALL for compilation instructions. (The only thing
+installed is the documentation; regex.c is compiled into regex.o, but
+not installed anywhere.)
+
+The subdirectory `doc' contains a (programmers') manual for the library.
+It's probably out-of-date. Improvements are welcome.
+
+The subdirectory `test' contains the various tests we've written.
+
+We know this code is not as fast as it might be. If you have specific
+suggestions, profiling results, or other such useful information to
+report, please do.
+
+Emacs 18 is not going use this revised regex (but Emacs 19 will). If
+you want to try it with Emacs 18, apply the patch at the end of this
+file first.
+
+Mail bug reports to bug-gnu-utils@prep.ai.mit.edu.
+
+Please include an actual regular expression that fails (and the syntax
+used to compile it); without that, there's no way to reproduce the bug,
+so there's no way we can fix it. Even if you include a patch, also
+include the regular expression in error; otherwise, we can't know for
+sure what you're trying to fix.
+
+Here is the patch to make this version of regex work with Emacs 18.
+
+*** ORIG/search.c Tue Jan 8 13:04:55 1991
+--- search.c Sun Jan 5 10:57:00 1992
+***************
+*** 25,26 ****
+--- 25,28 ----
+ #include "commands.h"
++
++ #include <sys/types.h>
+ #include "regex.h"
+***************
+*** 477,479 ****
+ /* really needed. */
+! && *(searchbuf.buffer) == (char) exactn /* first item is "exact match" */
+ && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
+--- 479,482 ----
+ /* really needed. */
+! /* first item is "exact match" */
+! && *(searchbuf.buffer) == (char) RE_EXACTN_VALUE
+ && searchbuf.buffer[1] + 2 == searchbuf.used) /*first is ONLY item */
+***************
+*** 1273,1275 ****
+ searchbuf.allocated = 100;
+! searchbuf.buffer = (char *) malloc (searchbuf.allocated);
+ searchbuf.fastmap = search_fastmap;
+--- 1276,1278 ----
+ searchbuf.allocated = 100;
+! searchbuf.buffer = (unsigned char *) malloc (searchbuf.allocated);
+ searchbuf.fastmap = search_fastmap;
diff --git a/gnu/lib/libregex/VERSION b/gnu/lib/libregex/VERSION
new file mode 100644
index 0000000..7182be2
--- /dev/null
+++ b/gnu/lib/libregex/VERSION
@@ -0,0 +1,3 @@
+GNU regex version 0.12
+
+complete, unmodified regex sources are available from prep.ai.mit.edu.
diff --git a/gnu/lib/libregex/config.status b/gnu/lib/libregex/config.status
new file mode 100644
index 0000000..1b276aa
--- /dev/null
+++ b/gnu/lib/libregex/config.status
@@ -0,0 +1,59 @@
+#!/bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host sun-lamp.cs.berkeley.edu:
+#
+# configure
+
+for arg
+do
+ case "$arg" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ exec /bin/sh configure ;;
+ *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;;
+ esac
+done
+
+trap 'rm -f Makefile doc/Makefile test/Makefile; exit 1' 1 3 15
+CC='gcc'
+INSTALL='/usr/bin/install -c'
+INSTALL_PROGRAM='$(INSTALL)'
+INSTALL_DATA='$(INSTALL) -m 644'
+CPP='${CC-cc} -E'
+ALLOCA=''
+LIBS=''
+srcdir='.'
+DEFS=' -DHAVE_STRING_H=1'
+prefix='/usr'
+exec_prefix='${prefix}'
+prsub='s%^prefix\([ ]*\)=\([ ]*\).*$%prefix\1=\2/usr%
+s%^exec_prefix\([ ]*\)=\([ ]*\).*$%exec_prefix\1=\2${prefix}%'
+
+top_srcdir=$srcdir
+for file in .. Makefile doc/Makefile test/Makefile; do if [ "x$file" != "x.." ]; then
+ srcdir=$top_srcdir
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ dir=`echo $file|sed 's%/[^/][^/]*$%%'`
+ if test "$dir" != "$file"; then
+ test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
+ test ! -d $dir && mkdir $dir
+ fi
+ echo creating $file
+ rm -f $file
+ echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file
+ sed -e "
+$prsub
+s%@CC@%$CC%g
+s%@INSTALL@%$INSTALL%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@LIBS@%$LIBS%g
+s%@srcdir@%$srcdir%g
+s%@DEFS@%$DEFS%
+" $top_srcdir/${file}.in >> $file
+fi; done
+
+exit 0
diff --git a/gnu/lib/libregex/configure b/gnu/lib/libregex/configure
new file mode 100644
index 0000000..29c5b80
--- /dev/null
+++ b/gnu/lib/libregex/configure
@@ -0,0 +1,462 @@
+#!/bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf.
+# Copyright (C) 1991, 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Usage: configure [--srcdir=DIR] [--host=HOST] [--gas] [--nfp] [--no-create]
+# [--prefix=PREFIX] [--exec-prefix=PREFIX] [--with-PACKAGE] [TARGET]
+# Ignores all args except --srcdir, --prefix, --exec-prefix, --no-create, and
+# --with-PACKAGE unless this script has special code to handle it.
+
+
+for arg
+do
+ # Handle --exec-prefix with a space before the argument.
+ if test x$next_exec_prefix = xyes; then exec_prefix=$arg; next_exec_prefix=
+ # Handle --host with a space before the argument.
+ elif test x$next_host = xyes; then next_host=
+ # Handle --prefix with a space before the argument.
+ elif test x$next_prefix = xyes; then prefix=$arg; next_prefix=
+ # Handle --srcdir with a space before the argument.
+ elif test x$next_srcdir = xyes; then srcdir=$arg; next_srcdir=
+ else
+ case $arg in
+ # For backward compatibility, also recognize exact --exec_prefix.
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* | --exec=* | --exe=* | --ex=* | --e=*)
+ exec_prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- | --exec | --exe | --ex | --e)
+ next_exec_prefix=yes ;;
+
+ -gas | --gas | --ga | --g) ;;
+
+ -host=* | --host=* | --hos=* | --ho=* | --h=*) ;;
+ -host | --host | --hos | --ho | --h)
+ next_host=yes ;;
+
+ -nfp | --nfp | --nf) ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre | --no-cr | --no-c | --no- | --no)
+ no_create=1 ;;
+
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=`echo $arg | sed 's/[-a-z_]*=//'` ;;
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ next_prefix=yes ;;
+
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=* | --s=*)
+ srcdir=`echo $arg | sed 's/[-a-z_]*=//'` ;;
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr | --s)
+ next_srcdir=yes ;;
+
+ -with-* | --with-*)
+ package=`echo $arg|sed 's/-*with-//'`
+ # Delete all the valid chars; see if any are left.
+ if test -n "`echo $package|sed 's/[-a-zA-Z0-9_]*//g'`"; then
+ echo "configure: $package: invalid package name" >&2; exit 1
+ fi
+ eval "with_`echo $package|sed s/-/_/g`=1" ;;
+
+ *) ;;
+ esac
+ fi
+done
+
+trap 'rm -f conftest* core; exit 1' 1 3 15
+
+rm -f conftest*
+compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
+
+# 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.
+unique_file=regex.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ srcdirdefaulted=yes
+ # Try the directory containing this script, then `..'.
+ prog=$0
+ confdir=`echo $prog|sed 's%/[^/][^/]*$%%'`
+ test "X$confdir" = "X$prog" && confdir=.
+ srcdir=$confdir
+ if test ! -r $srcdir/$unique_file; then
+ srcdir=..
+ fi
+fi
+if test ! -r $srcdir/$unique_file; then
+ if test x$srcdirdefaulted = xyes; then
+ echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2
+ else
+ echo "configure: Can not find sources in \`${srcdir}'." 1>&2
+ fi
+ exit 1
+fi
+# Preserve a srcdir of `.' to avoid automounter screwups with pwd.
+# But we can't avoid them for `..', to make subdirectories work.
+case $srcdir in
+ .|/*|~*) ;;
+ *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute.
+esac
+
+
+if test -z "$CC"; then
+ echo checking for gcc
+ saveifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$saveifs"
+fi
+test -z "$CC" && CC="cc"
+
+# Find out if we are using GNU C, under whatever name.
+cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes
+#endif
+EOF
+${CC-cc} -E conftest.c > conftest.out 2>&1
+if egrep yes conftest.out >/dev/null 2>&1; then
+ GCC=1 # For later tests.
+fi
+rm -f conftest*
+
+# Make sure to not get the incompatible SysV /etc/install and
+# /usr/sbin/install, which might be in PATH before a BSD-like install,
+# or the SunOS /usr/etc/install directory, or the AIX /bin/install,
+# or the AFS install, which mishandles nonexistent args. (Sigh.)
+if test -z "$INSTALL"; then
+ echo checking for install
+ saveifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ case $dir in
+ /etc|/usr/sbin|/usr/etc|/usr/afsws/bin) ;;
+ *)
+ if test -f $dir/install; then
+ if grep dspmsg $dir/install >/dev/null 2>&1; then
+ : # AIX
+ else
+ INSTALL="$dir/install -c"
+ INSTALL_PROGRAM='$(INSTALL)'
+ INSTALL_DATA='$(INSTALL) -m 644'
+ break
+ fi
+ fi
+ ;;
+ esac
+ done
+ IFS="$saveifs"
+fi
+INSTALL=${INSTALL-cp}
+INSTALL_PROGRAM=${INSTALL_PROGRAM-'$(INSTALL)'}
+INSTALL_DATA=${INSTALL_DATA-'$(INSTALL)'}
+
+
+echo checking for AIX
+echo checking how to run the C preprocessor
+if test -z "$CPP"; then
+ CPP='${CC-cc} -E'
+ cat > conftest.c <<EOF
+#include <stdio.h>
+EOF
+err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
+if test -z "$err"; then
+ :
+else
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+
+cat > conftest.c <<EOF
+#ifdef _AIX
+ yes
+#endif
+
+EOF
+eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
+if egrep "yes" conftest.out >/dev/null 2>&1; then
+ DEFS="$DEFS -D_ALL_SOURCE=1"
+fi
+rm -f conftest*
+
+
+echo checking for DYNIX/ptx libseq
+cat > conftest.c <<EOF
+#if defined(_SEQUENT_)
+ yes
+#endif
+
+EOF
+eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
+if egrep "yes" conftest.out >/dev/null 2>&1; then
+ SEQUENT=1
+fi
+rm -f conftest*
+
+test -n "$SEQUENT" && test -f /usr/lib/libseq.a &&
+ LIBS="$LIBS -lseq"
+
+echo checking for POSIXized ISC
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ ISC=1 # If later tests want to check for ISC.
+ DEFS="$DEFS -D_POSIX_SOURCE=1"
+ if test -n "$GCC"; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+fi
+
+echo checking for minix/config.h
+cat > conftest.c <<EOF
+#include <minix/config.h>
+EOF
+err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
+if test -z "$err"; then
+ MINIX=1
+fi
+rm -f conftest*
+
+# The Minix shell can't assign to the same variable on the same line!
+if test -n "$MINIX"; then
+ DEFS="$DEFS -D_POSIX_SOURCE=1"
+ DEFS="$DEFS -D_POSIX_1_SOURCE=2"
+ DEFS="$DEFS -D_MINIX=1"
+fi
+
+
+echo checking for ANSI C header files
+cat > conftest.c <<EOF
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
+if test -z "$err"; then
+ # SunOS string.h does not declare mem*, contrary to ANSI.
+echo '#include <string.h>' > conftest.c
+eval "$CPP $DEFS conftest.c > conftest.out 2>&1"
+if egrep "memchr" conftest.out >/dev/null 2>&1; then
+ # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+cat > conftest.c <<EOF
+#include <ctype.h>
+#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
+eval $compile
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ DEFS="$DEFS -DSTDC_HEADERS=1"
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+
+fi
+rm -f conftest*
+
+for hdr in string.h
+do
+trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'`
+echo checking for ${hdr}
+cat > conftest.c <<EOF
+#include <${hdr}>
+EOF
+err=`eval "$CPP $DEFS conftest.c 2>&1 >/dev/null"`
+if test -z "$err"; then
+ DEFS="$DEFS -D${trhdr}=1"
+fi
+rm -f conftest*
+done
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo checking for working alloca.h
+cat > conftest.c <<EOF
+#include <alloca.h>
+main() { exit(0); }
+t() { char *p = alloca(2 * sizeof(int)); }
+EOF
+if eval $compile; then
+ DEFS="$DEFS -DHAVE_ALLOCA_H=1"
+fi
+rm -f conftest*
+
+decl="#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else
+#ifdef _AIX
+ #pragma alloca
+#else
+char *alloca ();
+#endif
+#endif
+#endif
+"
+echo checking for alloca
+cat > conftest.c <<EOF
+$decl
+main() { exit(0); }
+t() { char *p = (char *) alloca(1); }
+EOF
+if eval $compile; then
+ :
+else
+ alloca_missing=1
+fi
+rm -f conftest*
+
+if test -n "$alloca_missing"; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.o
+fi
+
+prog='/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *p;
+char **p2;
+/* HPUX 7.0 cc rejects these. */
+++p;
+p2 = (char const* const*) p;'
+echo checking for working const
+cat > conftest.c <<EOF
+
+main() { exit(0); }
+t() { $prog }
+EOF
+if eval $compile; then
+ :
+else
+ DEFS="$DEFS -Dconst="
+fi
+rm -f conftest*
+
+
+if test -z "$prefix"
+then
+ echo checking for gcc to derive installation directory prefix
+ saveifs="$IFS"; IFS="$IFS:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test $dir != . && test -f $dir/gcc; then
+ # Not all systems have dirname.
+ prefix=`echo $dir|sed 's%/[^/][^/]*$%%'`
+ break
+ fi
+ done
+ IFS="$saveifs"
+fi
+
+
+if test -n "$prefix"; then
+ test -z "$exec_prefix" && exec_prefix='${prefix}'
+ prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%"
+fi
+if test -n "$exec_prefix"; then
+ prsub="$prsub
+s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%\
+exec_prefix\\1=\\2$exec_prefix%"
+fi
+
+trap 'rm -f config.status; exit 1' 1 3 15
+echo creating config.status
+rm -f config.status
+cat > config.status <<EOF
+#!/bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null`:
+#
+# $0 $*
+
+for arg
+do
+ case "\$arg" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ exec /bin/sh $0 $* ;;
+ *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;;
+ esac
+done
+
+trap 'rm -f Makefile doc/Makefile test/Makefile; exit 1' 1 3 15
+CC='$CC'
+INSTALL='$INSTALL'
+INSTALL_PROGRAM='$INSTALL_PROGRAM'
+INSTALL_DATA='$INSTALL_DATA'
+CPP='$CPP'
+ALLOCA='$ALLOCA'
+LIBS='$LIBS'
+srcdir='$srcdir'
+DEFS='$DEFS'
+prefix='$prefix'
+exec_prefix='$exec_prefix'
+prsub='$prsub'
+EOF
+cat >> config.status <<\EOF
+
+top_srcdir=$srcdir
+for file in .. Makefile doc/Makefile test/Makefile; do if [ "x$file" != "x.." ]; then
+ srcdir=$top_srcdir
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ dir=`echo $file|sed 's%/[^/][^/]*$%%'`
+ if test "$dir" != "$file"; then
+ test "$top_srcdir" != . && srcdir=$top_srcdir/$dir
+ test ! -d $dir && mkdir $dir
+ fi
+ echo creating $file
+ rm -f $file
+ echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file
+ sed -e "
+$prsub
+s%@CC@%$CC%g
+s%@INSTALL@%$INSTALL%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CPP@%$CPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@LIBS@%$LIBS%g
+s%@srcdir@%$srcdir%g
+s%@DEFS@%$DEFS%
+" $top_srcdir/${file}.in >> $file
+fi; done
+
+exit 0
+EOF
+chmod +x config.status
+test -n "$no_create" || ./config.status
+
diff --git a/gnu/lib/libregex/configure.in b/gnu/lib/libregex/configure.in
new file mode 100644
index 0000000..f0fc780
--- /dev/null
+++ b/gnu/lib/libregex/configure.in
@@ -0,0 +1,23 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(regex.c)
+
+AC_PROG_CC
+AC_PROG_INSTALL
+
+dnl I'm not sure if AC_AIX and AC_DYNIX_SEQ are really necessary. The
+dnl Autoconf documentation isn't specific about which BSD functions they
+dnl provide.
+AC_AIX
+AC_DYNIX_SEQ
+AC_ISC_POSIX
+AC_MINIX
+
+AC_STDC_HEADERS
+AC_HAVE_HEADERS(string.h)
+
+AC_ALLOCA
+AC_CONST
+
+AC_PREFIX(gcc)
+
+AC_OUTPUT(Makefile doc/Makefile test/Makefile)
diff --git a/gnu/lib/libregex/doc/Makefile b/gnu/lib/libregex/doc/Makefile
new file mode 100644
index 0000000..1e79f5d
--- /dev/null
+++ b/gnu/lib/libregex/doc/Makefile
@@ -0,0 +1,9 @@
+INFO = regex
+CLEANFILES += regex.texi
+
+regex.texi: xregex.texi ../regex.h
+ awk -f ${.CURDIR}/include.awk -vsource=${.CURDIR}/../regex.h \
+ < ${.CURDIR}/xregex.texi \
+ | expand >$@
+
+.include <bsd.info.mk>
diff --git a/gnu/lib/libregex/doc/include.awk b/gnu/lib/libregex/doc/include.awk
new file mode 100644
index 0000000..a1df3f8
--- /dev/null
+++ b/gnu/lib/libregex/doc/include.awk
@@ -0,0 +1,19 @@
+# Assume `source' is set with -vsource=filename on the command line.
+#
+/^\[\[\[/ { inclusion = $2; # name of the thing to include.
+ printing = 0;
+ while ((getline line < source) > 0)
+ {
+ if (match (line, "\\[\\[\\[end " inclusion "\\]\\]\\]"))
+ printing = 0;
+
+ if (printing)
+ print line;
+
+ if (match (line,"\\[\\[\\[begin " inclusion "\\]\\]\\]"))
+ printing = 1;
+ }
+ close (source);
+ next;
+ }
+ { print }
diff --git a/gnu/lib/libregex/doc/xregex.texi b/gnu/lib/libregex/doc/xregex.texi
new file mode 100644
index 0000000..9292b35
--- /dev/null
+++ b/gnu/lib/libregex/doc/xregex.texi
@@ -0,0 +1,3021 @@
+\input texinfo
+@c %**start of header
+@setfilename regex.info
+@settitle Regex
+@c %**end of header
+
+@c \\{fill-paragraph} works better (for me, anyway) if the text in the
+@c source file isn't indented.
+@paragraphindent 2
+
+@c Define a new index for our magic constants.
+@defcodeindex cn
+
+@c Put everything in one index (arbitrarily chosen to be the concept index).
+@syncodeindex cn cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+@syncodeindex vr cp
+
+@c Here is what we use in the Info `dir' file:
+@c * Regex: (regex). Regular expression library.
+
+
+@ifinfo
+This file documents the GNU regular expression library.
+
+Copyright (C) 1992, 1993 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 also that the
+section entitled ``GNU General Public License'' is included exactly as
+in the original, 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,
+except that the section entitled ``GNU General Public License'' may be
+included in a translation approved by the Free Software Foundation
+instead of in the original English.
+@end ifinfo
+
+
+@titlepage
+
+@title Regex
+@subtitle edition 0.12a
+@subtitle 19 September 1992
+@author Kathryn A. Hargreaves
+@author Karl Berry
+
+@page
+
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992 Free Software Foundation.
+
+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
+section entitled ``GNU General Public License'' is included exactly as
+in the original, 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,
+except that the section entitled ``GNU General Public License'' may be
+included in a translation approved by the Free Software Foundation
+instead of in the original English.
+
+@end titlepage
+
+
+@ifinfo
+@node Top, Overview, (dir), (dir)
+@top Regular Expression Library
+
+This manual documents how to program with the GNU regular expression
+library. This is edition 0.12a of the manual, 19 September 1992.
+
+The first part of this master menu lists the major nodes in this Info
+document, including the index. The rest of the menu lists all the
+lower level nodes in the document.
+
+@menu
+* Overview::
+* Regular Expression Syntax::
+* Common Operators::
+* GNU Operators::
+* GNU Emacs Operators::
+* What Gets Matched?::
+* Programming with Regex::
+* Copying:: Copying and sharing Regex.
+* Index:: General index.
+ --- The Detailed Node Listing ---
+
+Regular Expression Syntax
+
+* Syntax Bits::
+* Predefined Syntaxes::
+* Collating Elements vs. Characters::
+* The Backslash Character::
+
+Common Operators
+
+* Match-self Operator:: Ordinary characters.
+* Match-any-character Operator:: .
+* Concatenation Operator:: Juxtaposition.
+* Repetition Operators:: * + ? @{@}
+* Alternation Operator:: |
+* List Operators:: [...] [^...]
+* Grouping Operators:: (...)
+* Back-reference Operator:: \digit
+* Anchoring Operators:: ^ $
+
+Repetition Operators
+
+* Match-zero-or-more Operator:: *
+* Match-one-or-more Operator:: +
+* Match-zero-or-one Operator:: ?
+* Interval Operators:: @{@}
+
+List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]})
+
+* Character Class Operators:: [:class:]
+* Range Operator:: start-end
+
+Anchoring Operators
+
+* Match-beginning-of-line Operator:: ^
+* Match-end-of-line Operator:: $
+
+GNU Operators
+
+* Word Operators::
+* Buffer Operators::
+
+Word Operators
+
+* Non-Emacs Syntax Tables::
+* Match-word-boundary Operator:: \b
+* Match-within-word Operator:: \B
+* Match-beginning-of-word Operator:: \<
+* Match-end-of-word Operator:: \>
+* Match-word-constituent Operator:: \w
+* Match-non-word-constituent Operator:: \W
+
+Buffer Operators
+
+* Match-beginning-of-buffer Operator:: \`
+* Match-end-of-buffer Operator:: \'
+
+GNU Emacs Operators
+
+* Syntactic Class Operators::
+
+Syntactic Class Operators
+
+* Emacs Syntax Tables::
+* Match-syntactic-class Operator:: \sCLASS
+* Match-not-syntactic-class Operator:: \SCLASS
+
+Programming with Regex
+
+* GNU Regex Functions::
+* POSIX Regex Functions::
+* BSD Regex Functions::
+
+GNU Regex Functions
+
+* GNU Pattern Buffers:: The re_pattern_buffer type.
+* GNU Regular Expression Compiling:: re_compile_pattern ()
+* GNU Matching:: re_match ()
+* GNU Searching:: re_search ()
+* Matching/Searching with Split Data:: re_match_2 (), re_search_2 ()
+* Searching with Fastmaps:: re_compile_fastmap ()
+* GNU Translate Tables:: The `translate' field.
+* Using Registers:: The re_registers type and related fns.
+* Freeing GNU Pattern Buffers:: regfree ()
+
+POSIX Regex Functions
+
+* POSIX Pattern Buffers:: The regex_t type.
+* POSIX Regular Expression Compiling:: regcomp ()
+* POSIX Matching:: regexec ()
+* Reporting Errors:: regerror ()
+* Using Byte Offsets:: The regmatch_t type.
+* Freeing POSIX Pattern Buffers:: regfree ()
+
+BSD Regex Functions
+
+* BSD Regular Expression Compiling:: re_comp ()
+* BSD Searching:: re_exec ()
+@end menu
+@end ifinfo
+@node Overview, Regular Expression Syntax, Top, Top
+@chapter Overview
+
+A @dfn{regular expression} (or @dfn{regexp}, or @dfn{pattern}) is a text
+string that describes some (mathematical) set of strings. A regexp
+@var{r} @dfn{matches} a string @var{s} if @var{s} is in the set of
+strings described by @var{r}.
+
+Using the Regex library, you can:
+
+@itemize @bullet
+
+@item
+see if a string matches a specified pattern as a whole, and
+
+@item
+search within a string for a substring matching a specified pattern.
+
+@end itemize
+
+Some regular expressions match only one string, i.e., the set they
+describe has only one member. For example, the regular expression
+@samp{foo} matches the string @samp{foo} and no others. Other regular
+expressions match more than one string, i.e., the set they describe has
+more than one member. For example, the regular expression @samp{f*}
+matches the set of strings made up of any number (including zero) of
+@samp{f}s. As you can see, some characters in regular expressions match
+themselves (such as @samp{f}) and some don't (such as @samp{*}); the
+ones that don't match themselves instead let you specify patterns that
+describe many different strings.
+
+To either match or search for a regular expression with the Regex
+library functions, you must first compile it with a Regex pattern
+compiling function. A @dfn{compiled pattern} is a regular expression
+converted to the internal format used by the library functions. Once
+you've compiled a pattern, you can use it for matching or searching any
+number of times.
+
+The Regex library consists of two source files: @file{regex.h} and
+@file{regex.c}.
+@pindex regex.h
+@pindex regex.c
+Regex provides three groups of functions with which you can operate on
+regular expressions. One group---the @sc{gnu} group---is more powerful
+but not completely compatible with the other two, namely the @sc{posix}
+and Berkeley @sc{unix} groups; its interface was designed specifically
+for @sc{gnu}. The other groups have the same interfaces as do the
+regular expression functions in @sc{posix} and Berkeley
+@sc{unix}.
+
+We wrote this chapter with programmers in mind, not users of
+programs---such as Emacs---that use Regex. We describe the Regex
+library in its entirety, not how to write regular expressions that a
+particular program understands.
+
+
+@node Regular Expression Syntax, Common Operators, Overview, Top
+@chapter Regular Expression Syntax
+
+@cindex regular expressions, syntax of
+@cindex syntax of regular expressions
+
+@dfn{Characters} are things you can type. @dfn{Operators} are things in
+a regular expression that match one or more characters. You compose
+regular expressions from operators, which in turn you specify using one
+or more characters.
+
+Most characters represent what we call the match-self operator, i.e.,
+they match themselves; we call these characters @dfn{ordinary}. Other
+characters represent either all or parts of fancier operators; e.g.,
+@samp{.} represents what we call the match-any-character operator
+(which, no surprise, matches (almost) any character); we call these
+characters @dfn{special}. Two different things determine what
+characters represent what operators:
+
+@enumerate
+@item
+the regular expression syntax your program has told the Regex library to
+recognize, and
+
+@item
+the context of the character in the regular expression.
+@end enumerate
+
+In the following sections, we describe these things in more detail.
+
+@menu
+* Syntax Bits::
+* Predefined Syntaxes::
+* Collating Elements vs. Characters::
+* The Backslash Character::
+@end menu
+
+
+@node Syntax Bits, Predefined Syntaxes, , Regular Expression Syntax
+@section Syntax Bits
+
+@cindex syntax bits
+
+In any particular syntax for regular expressions, some characters are
+always special, others are sometimes special, and others are never
+special. The particular syntax that Regex recognizes for a given
+regular expression depends on the value in the @code{syntax} field of
+the pattern buffer of that regular expression.
+
+You get a pattern buffer by compiling a regular expression. @xref{GNU
+Pattern Buffers}, and @ref{POSIX Pattern Buffers}, for more information
+on pattern buffers. @xref{GNU Regular Expression Compiling}, @ref{POSIX
+Regular Expression Compiling}, and @ref{BSD Regular Expression
+Compiling}, for more information on compiling.
+
+Regex considers the value of the @code{syntax} field to be a collection
+of bits; we refer to these bits as @dfn{syntax bits}. In most cases,
+they affect what characters represent what operators. We describe the
+meanings of the operators to which we refer in @ref{Common Operators},
+@ref{GNU Operators}, and @ref{GNU Emacs Operators}.
+
+For reference, here is the complete list of syntax bits, in alphabetical
+order:
+
+@table @code
+
+@cnindex RE_BACKSLASH_ESCAPE_IN_LIST
+@item RE_BACKSLASH_ESCAPE_IN_LISTS
+If this bit is set, then @samp{\} inside a list (@pxref{List Operators}
+quotes (makes ordinary, if it's special) the following character; if
+this bit isn't set, then @samp{\} is an ordinary character inside lists.
+(@xref{The Backslash Character}, for what `\' does outside of lists.)
+
+@cnindex RE_BK_PLUS_QM
+@item RE_BK_PLUS_QM
+If this bit is set, then @samp{\+} represents the match-one-or-more
+operator and @samp{\?} represents the match-zero-or-more operator; if
+this bit isn't set, then @samp{+} represents the match-one-or-more
+operator and @samp{?} represents the match-zero-or-one operator. This
+bit is irrelevant if @code{RE_LIMITED_OPS} is set.
+
+@cnindex RE_CHAR_CLASSES
+@item RE_CHAR_CLASSES
+If this bit is set, then you can use character classes in lists; if this
+bit isn't set, then you can't.
+
+@cnindex RE_CONTEXT_INDEP_ANCHORS
+@item RE_CONTEXT_INDEP_ANCHORS
+If this bit is set, then @samp{^} and @samp{$} are special anywhere outside
+a list; if this bit isn't set, then these characters are special only in
+certain contexts. @xref{Match-beginning-of-line Operator}, and
+@ref{Match-end-of-line Operator}.
+
+@cnindex RE_CONTEXT_INDEP_OPS
+@item RE_CONTEXT_INDEP_OPS
+If this bit is set, then certain characters are special anywhere outside
+a list; if this bit isn't set, then those characters are special only in
+some contexts and are ordinary elsewhere. Specifically, if this bit
+isn't set then @samp{*}, and (if the syntax bit @code{RE_LIMITED_OPS}
+isn't set) @samp{+} and @samp{?} (or @samp{\+} and @samp{\?}, depending
+on the syntax bit @code{RE_BK_PLUS_QM}) represent repetition operators
+only if they're not first in a regular expression or just after an
+open-group or alternation operator. The same holds for @samp{@{} (or
+@samp{\@{}, depending on the syntax bit @code{RE_NO_BK_BRACES}) if
+it is the beginning of a valid interval and the syntax bit
+@code{RE_INTERVALS} is set.
+
+@cnindex RE_CONTEXT_INVALID_OPS
+@item RE_CONTEXT_INVALID_OPS
+If this bit is set, then repetition and alternation operators can't be
+in certain positions within a regular expression. Specifically, the
+regular expression is invalid if it has:
+
+@itemize @bullet
+
+@item
+a repetition operator first in the regular expression or just after a
+match-beginning-of-line, open-group, or alternation operator; or
+
+@item
+an alternation operator first or last in the regular expression, just
+before a match-end-of-line operator, or just after an alternation or
+open-group operator.
+
+@end itemize
+
+If this bit isn't set, then you can put the characters representing the
+repetition and alternation characters anywhere in a regular expression.
+Whether or not they will in fact be operators in certain positions
+depends on other syntax bits.
+
+@cnindex RE_DOT_NEWLINE
+@item RE_DOT_NEWLINE
+If this bit is set, then the match-any-character operator matches
+a newline; if this bit isn't set, then it doesn't.
+
+@cnindex RE_DOT_NOT_NULL
+@item RE_DOT_NOT_NULL
+If this bit is set, then the match-any-character operator doesn't match
+a null character; if this bit isn't set, then it does.
+
+@cnindex RE_INTERVALS
+@item RE_INTERVALS
+If this bit is set, then Regex recognizes interval operators; if this bit
+isn't set, then it doesn't.
+
+@cnindex RE_LIMITED_OPS
+@item RE_LIMITED_OPS
+If this bit is set, then Regex doesn't recognize the match-one-or-more,
+match-zero-or-one or alternation operators; if this bit isn't set, then
+it does.
+
+@cnindex RE_NEWLINE_ALT
+@item RE_NEWLINE_ALT
+If this bit is set, then newline represents the alternation operator; if
+this bit isn't set, then newline is ordinary.
+
+@cnindex RE_NO_BK_BRACES
+@item RE_NO_BK_BRACES
+If this bit is set, then @samp{@{} represents the open-interval operator
+and @samp{@}} represents the close-interval operator; if this bit isn't
+set, then @samp{\@{} represents the open-interval operator and
+@samp{\@}} represents the close-interval operator. This bit is relevant
+only if @code{RE_INTERVALS} is set.
+
+@cnindex RE_NO_BK_PARENS
+@item RE_NO_BK_PARENS
+If this bit is set, then @samp{(} represents the open-group operator and
+@samp{)} represents the close-group operator; if this bit isn't set, then
+@samp{\(} represents the open-group operator and @samp{\)} represents
+the close-group operator.
+
+@cnindex RE_NO_BK_REFS
+@item RE_NO_BK_REFS
+If this bit is set, then Regex doesn't recognize @samp{\}@var{digit} as
+the back reference operator; if this bit isn't set, then it does.
+
+@cnindex RE_NO_BK_VBAR
+@item RE_NO_BK_VBAR
+If this bit is set, then @samp{|} represents the alternation operator;
+if this bit isn't set, then @samp{\|} represents the alternation
+operator. This bit is irrelevant if @code{RE_LIMITED_OPS} is set.
+
+@cnindex RE_NO_EMPTY_RANGES
+@item RE_NO_EMPTY_RANGES
+If this bit is set, then a regular expression with a range whose ending
+point collates lower than its starting point is invalid; if this bit
+isn't set, then Regex considers such a range to be empty.
+
+@cnindex RE_UNMATCHED_RIGHT_PAREN_ORD
+@item RE_UNMATCHED_RIGHT_PAREN_ORD
+If this bit is set and the regular expression has no matching open-group
+operator, then Regex considers what would otherwise be a close-group
+operator (based on how @code{RE_NO_BK_PARENS} is set) to match @samp{)}.
+
+@end table
+
+
+@node Predefined Syntaxes, Collating Elements vs. Characters, Syntax Bits, Regular Expression Syntax
+@section Predefined Syntaxes
+
+If you're programming with Regex, you can set a pattern buffer's
+(@pxref{GNU Pattern Buffers}, and @ref{POSIX Pattern Buffers})
+@code{syntax} field either to an arbitrary combination of syntax bits
+(@pxref{Syntax Bits}) or else to the configurations defined by Regex.
+These configurations define the syntaxes used by certain
+programs---@sc{gnu} Emacs,
+@cindex Emacs
+@sc{posix} Awk,
+@cindex POSIX Awk
+traditional Awk,
+@cindex Awk
+Grep,
+@cindex Grep
+@cindex Egrep
+Egrep---in addition to syntaxes for @sc{posix} basic and extended
+regular expressions.
+
+The predefined syntaxes--taken directly from @file{regex.h}---are:
+
+@example
+[[[ syntaxes ]]]
+@end example
+
+@node Collating Elements vs. Characters, The Backslash Character, Predefined Syntaxes, Regular Expression Syntax
+@section Collating Elements vs.@: Characters
+
+@sc{posix} generalizes the notion of a character to that of a
+collating element. It defines a @dfn{collating element} to be ``a
+sequence of one or more bytes defined in the current collating sequence
+as a unit of collation.''
+
+This generalizes the notion of a character in
+two ways. First, a single character can map into two or more collating
+elements. For example, the German
+@tex
+`\ss'
+@end tex
+@ifinfo
+``es-zet''
+@end ifinfo
+collates as the collating element @samp{s} followed by another collating
+element @samp{s}. Second, two or more characters can map into one
+collating element. For example, the Spanish @samp{ll} collates after
+@samp{l} and before @samp{m}.
+
+Since @sc{posix}'s ``collating element'' preserves the essential idea of
+a ``character,'' we use the latter, more familiar, term in this document.
+
+@node The Backslash Character, , Collating Elements vs. Characters, Regular Expression Syntax
+@section The Backslash Character
+
+@cindex \
+The @samp{\} character has one of four different meanings, depending on
+the context in which you use it and what syntax bits are set
+(@pxref{Syntax Bits}). It can: 1) stand for itself, 2) quote the next
+character, 3) introduce an operator, or 4) do nothing.
+
+@enumerate
+@item
+It stands for itself inside a list
+(@pxref{List Operators}) if the syntax bit
+@code{RE_BACKSLASH_ESCAPE_IN_LISTS} is not set. For example, @samp{[\]}
+would match @samp{\}.
+
+@item
+It quotes (makes ordinary, if it's special) the next character when you
+use it either:
+
+@itemize @bullet
+@item
+outside a list,@footnote{Sometimes
+you don't have to explicitly quote special characters to make
+them ordinary. For instance, most characters lose any special meaning
+inside a list (@pxref{List Operators}). In addition, if the syntax bits
+@code{RE_CONTEXT_INVALID_OPS} and @code{RE_CONTEXT_INDEP_OPS}
+aren't set, then (for historical reasons) the matcher considers special
+characters ordinary if they are in contexts where the operations they
+represent make no sense; for example, then the match-zero-or-more
+operator (represented by @samp{*}) matches itself in the regular
+expression @samp{*foo} because there is no preceding expression on which
+it can operate. It is poor practice, however, to depend on this
+behavior; if you want a special character to be ordinary outside a list,
+it's better to always quote it, regardless.} or
+
+@item
+inside a list and the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is set.
+
+@end itemize
+
+@item
+It introduces an operator when followed by certain ordinary
+characters---sometimes only when certain syntax bits are set. See the
+cases @code{RE_BK_PLUS_QM}, @code{RE_NO_BK_BRACES}, @code{RE_NO_BK_VAR},
+@code{RE_NO_BK_PARENS}, @code{RE_NO_BK_REF} in @ref{Syntax Bits}. Also:
+
+@itemize @bullet
+@item
+@samp{\b} represents the match-word-boundary operator
+(@pxref{Match-word-boundary Operator}).
+
+@item
+@samp{\B} represents the match-within-word operator
+(@pxref{Match-within-word Operator}).
+
+@item
+@samp{\<} represents the match-beginning-of-word operator @*
+(@pxref{Match-beginning-of-word Operator}).
+
+@item
+@samp{\>} represents the match-end-of-word operator
+(@pxref{Match-end-of-word Operator}).
+
+@item
+@samp{\w} represents the match-word-constituent operator
+(@pxref{Match-word-constituent Operator}).
+
+@item
+@samp{\W} represents the match-non-word-constituent operator
+(@pxref{Match-non-word-constituent Operator}).
+
+@item
+@samp{\`} represents the match-beginning-of-buffer
+operator and @samp{\'} represents the match-end-of-buffer operator
+(@pxref{Buffer Operators}).
+
+@item
+If Regex was compiled with the C preprocessor symbol @code{emacs}
+defined, then @samp{\s@var{class}} represents the match-syntactic-class
+operator and @samp{\S@var{class}} represents the
+match-not-syntactic-class operator (@pxref{Syntactic Class Operators}).
+
+@end itemize
+
+@item
+In all other cases, Regex ignores @samp{\}. For example,
+@samp{\n} matches @samp{n}.
+
+@end enumerate
+
+@node Common Operators, GNU Operators, Regular Expression Syntax, Top
+@chapter Common Operators
+
+You compose regular expressions from operators. In the following
+sections, we describe the regular expression operators specified by
+@sc{posix}; @sc{gnu} also uses these. Most operators have more than one
+representation as characters. @xref{Regular Expression Syntax}, for
+what characters represent what operators under what circumstances.
+
+For most operators that can be represented in two ways, one
+representation is a single character and the other is that character
+preceded by @samp{\}. For example, either @samp{(} or @samp{\(}
+represents the open-group operator. Which one does depends on the
+setting of a syntax bit, in this case @code{RE_NO_BK_PARENS}. Why is
+this so? Historical reasons dictate some of the varying
+representations, while @sc{posix} dictates others.
+
+Finally, almost all characters lose any special meaning inside a list
+(@pxref{List Operators}).
+
+@menu
+* Match-self Operator:: Ordinary characters.
+* Match-any-character Operator:: .
+* Concatenation Operator:: Juxtaposition.
+* Repetition Operators:: * + ? @{@}
+* Alternation Operator:: |
+* List Operators:: [...] [^...]
+* Grouping Operators:: (...)
+* Back-reference Operator:: \digit
+* Anchoring Operators:: ^ $
+@end menu
+
+@node Match-self Operator, Match-any-character Operator, , Common Operators
+@section The Match-self Operator (@var{ordinary character})
+
+This operator matches the character itself. All ordinary characters
+(@pxref{Regular Expression Syntax}) represent this operator. For
+example, @samp{f} is always an ordinary character, so the regular
+expression @samp{f} matches only the string @samp{f}. In
+particular, it does @emph{not} match the string @samp{ff}.
+
+@node Match-any-character Operator, Concatenation Operator, Match-self Operator, Common Operators
+@section The Match-any-character Operator (@code{.})
+
+@cindex @samp{.}
+
+This operator matches any single printing or nonprinting character
+except it won't match a:
+
+@table @asis
+@item newline
+if the syntax bit @code{RE_DOT_NEWLINE} isn't set.
+
+@item null
+if the syntax bit @code{RE_DOT_NOT_NULL} is set.
+
+@end table
+
+The @samp{.} (period) character represents this operator. For example,
+@samp{a.b} matches any three-character string beginning with @samp{a}
+and ending with @samp{b}.
+
+@node Concatenation Operator, Repetition Operators, Match-any-character Operator, Common Operators
+@section The Concatenation Operator
+
+This operator concatenates two regular expressions @var{a} and @var{b}.
+No character represents this operator; you simply put @var{b} after
+@var{a}. The result is a regular expression that will match a string if
+@var{a} matches its first part and @var{b} matches the rest. For
+example, @samp{xy} (two match-self operators) matches @samp{xy}.
+
+@node Repetition Operators, Alternation Operator, Concatenation Operator, Common Operators
+@section Repetition Operators
+
+Repetition operators repeat the preceding regular expression a specified
+number of times.
+
+@menu
+* Match-zero-or-more Operator:: *
+* Match-one-or-more Operator:: +
+* Match-zero-or-one Operator:: ?
+* Interval Operators:: @{@}
+@end menu
+
+@node Match-zero-or-more Operator, Match-one-or-more Operator, , Repetition Operators
+@subsection The Match-zero-or-more Operator (@code{*})
+
+@cindex @samp{*}
+
+This operator repeats the smallest possible preceding regular expression
+as many times as necessary (including zero) to match the pattern.
+@samp{*} represents this operator. For example, @samp{o*}
+matches any string made up of zero or more @samp{o}s. Since this
+operator operates on the smallest preceding regular expression,
+@samp{fo*} has a repeating @samp{o}, not a repeating @samp{fo}. So,
+@samp{fo*} matches @samp{f}, @samp{fo}, @samp{foo}, and so on.
+
+Since the match-zero-or-more operator is a suffix operator, it may be
+useless as such when no regular expression precedes it. This is the
+case when it:
+
+@itemize @bullet
+@item
+is first in a regular expression, or
+
+@item
+follows a match-beginning-of-line, open-group, or alternation
+operator.
+
+@end itemize
+
+@noindent
+Three different things can happen in these cases:
+
+@enumerate
+@item
+If the syntax bit @code{RE_CONTEXT_INVALID_OPS} is set, then the
+regular expression is invalid.
+
+@item
+If @code{RE_CONTEXT_INVALID_OPS} isn't set, but
+@code{RE_CONTEXT_INDEP_OPS} is, then @samp{*} represents the
+match-zero-or-more operator (which then operates on the empty string).
+
+@item
+Otherwise, @samp{*} is ordinary.
+
+@end enumerate
+
+@cindex backtracking
+The matcher processes a match-zero-or-more operator by first matching as
+many repetitions of the smallest preceding regular expression as it can.
+Then it continues to match the rest of the pattern.
+
+If it can't match the rest of the pattern, it backtracks (as many times
+as necessary), each time discarding one of the matches until it can
+either match the entire pattern or be certain that it cannot get a
+match. For example, when matching @samp{ca*ar} against @samp{caaar},
+the matcher first matches all three @samp{a}s of the string with the
+@samp{a*} of the regular expression. However, it cannot then match the
+final @samp{ar} of the regular expression against the final @samp{r} of
+the string. So it backtracks, discarding the match of the last @samp{a}
+in the string. It can then match the remaining @samp{ar}.
+
+
+@node Match-one-or-more Operator, Match-zero-or-one Operator, Match-zero-or-more Operator, Repetition Operators
+@subsection The Match-one-or-more Operator (@code{+} or @code{\+})
+
+@cindex @samp{+}
+
+If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't recognize
+this operator. Otherwise, if the syntax bit @code{RE_BK_PLUS_QM} isn't
+set, then @samp{+} represents this operator; if it is, then @samp{\+}
+does.
+
+This operator is similar to the match-zero-or-more operator except that
+it repeats the preceding regular expression at least once;
+@pxref{Match-zero-or-more Operator}, for what it operates on, how some
+syntax bits affect it, and how Regex backtracks to match it.
+
+For example, supposing that @samp{+} represents the match-one-or-more
+operator; then @samp{ca+r} matches, e.g., @samp{car} and
+@samp{caaaar}, but not @samp{cr}.
+
+@node Match-zero-or-one Operator, Interval Operators, Match-one-or-more Operator, Repetition Operators
+@subsection The Match-zero-or-one Operator (@code{?} or @code{\?})
+@cindex @samp{?}
+
+If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't
+recognize this operator. Otherwise, if the syntax bit
+@code{RE_BK_PLUS_QM} isn't set, then @samp{?} represents this operator;
+if it is, then @samp{\?} does.
+
+This operator is similar to the match-zero-or-more operator except that
+it repeats the preceding regular expression once or not at all;
+@pxref{Match-zero-or-more Operator}, to see what it operates on, how
+some syntax bits affect it, and how Regex backtracks to match it.
+
+For example, supposing that @samp{?} represents the match-zero-or-one
+operator; then @samp{ca?r} matches both @samp{car} and @samp{cr}, but
+nothing else.
+
+@node Interval Operators, , Match-zero-or-one Operator, Repetition Operators
+@subsection Interval Operators (@code{@{} @dots{} @code{@}} or @code{\@{} @dots{} @code{\@}})
+
+@cindex interval expression
+@cindex @samp{@{}
+@cindex @samp{@}}
+@cindex @samp{\@{}
+@cindex @samp{\@}}
+
+If the syntax bit @code{RE_INTERVALS} is set, then Regex recognizes
+@dfn{interval expressions}. They repeat the smallest possible preceding
+regular expression a specified number of times.
+
+If the syntax bit @code{RE_NO_BK_BRACES} is set, @samp{@{} represents
+the @dfn{open-interval operator} and @samp{@}} represents the
+@dfn{close-interval operator} ; otherwise, @samp{\@{} and @samp{\@}} do.
+
+Specifically, supposing that @samp{@{} and @samp{@}} represent the
+open-interval and close-interval operators; then:
+
+@table @code
+@item @{@var{count}@}
+matches exactly @var{count} occurrences of the preceding regular
+expression.
+
+@item @{@var{min,}@}
+matches @var{min} or more occurrences of the preceding regular
+expression.
+
+@item @{@var{min, max}@}
+matches at least @var{min} but no more than @var{max} occurrences of
+the preceding regular expression.
+
+@end table
+
+The interval expression (but not necessarily the regular expression that
+contains it) is invalid if:
+
+@itemize @bullet
+@item
+@var{min} is greater than @var{max}, or
+
+@item
+any of @var{count}, @var{min}, or @var{max} are outside the range
+zero to @code{RE_DUP_MAX} (which symbol @file{regex.h}
+defines).
+
+@end itemize
+
+If the interval expression is invalid and the syntax bit
+@code{RE_NO_BK_BRACES} is set, then Regex considers all the
+characters in the would-be interval to be ordinary. If that bit
+isn't set, then the regular expression is invalid.
+
+If the interval expression is valid but there is no preceding regular
+expression on which to operate, then if the syntax bit
+@code{RE_CONTEXT_INVALID_OPS} is set, the regular expression is invalid.
+If that bit isn't set, then Regex considers all the characters---other
+than backslashes, which it ignores---in the would-be interval to be
+ordinary.
+
+
+@node Alternation Operator, List Operators, Repetition Operators, Common Operators
+@section The Alternation Operator (@code{|} or @code{\|})
+
+@kindex |
+@kindex \|
+@cindex alternation operator
+@cindex or operator
+
+If the syntax bit @code{RE_LIMITED_OPS} is set, then Regex doesn't
+recognize this operator. Otherwise, if the syntax bit
+@code{RE_NO_BK_VBAR} is set, then @samp{|} represents this operator;
+otherwise, @samp{\|} does.
+
+Alternatives match one of a choice of regular expressions:
+if you put the character(s) representing the alternation operator between
+any two regular expressions @var{a} and @var{b}, the result matches
+the union of the strings that @var{a} and @var{b} match. For
+example, supposing that @samp{|} is the alternation operator, then
+@samp{foo|bar|quux} would match any of @samp{foo}, @samp{bar} or
+@samp{quux}.
+
+@ignore
+@c Nobody needs to disallow empty alternatives any more.
+If the syntax bit @code{RE_NO_EMPTY_ALTS} is set, then if either of the regular
+expressions @var{a} or @var{b} is empty, the
+regular expression is invalid. More precisely, if this syntax bit is
+set, then the alternation operator can't:
+
+@itemize @bullet
+@item
+be first or last in a regular expression;
+
+@item
+follow either another alternation operator or an open-group operator
+(@pxref{Grouping Operators}); or
+
+@item
+precede a close-group operator.
+
+@end itemize
+
+@noindent
+For example, supposing @samp{(} and @samp{)} represent the open and
+close-group operators, then @samp{|foo}, @samp{foo|}, @samp{foo||bar},
+@samp{foo(|bar)}, and @samp{(foo|)bar} would all be invalid.
+@end ignore
+
+The alternation operator operates on the @emph{largest} possible
+surrounding regular expressions. (Put another way, it has the lowest
+precedence of any regular expression operator.)
+Thus, the only way you can
+delimit its arguments is to use grouping. For example, if @samp{(} and
+@samp{)} are the open and close-group operators, then @samp{fo(o|b)ar}
+would match either @samp{fooar} or @samp{fobar}. (@samp{foo|bar} would
+match @samp{foo} or @samp{bar}.)
+
+@cindex backtracking
+The matcher usually tries all combinations of alternatives so as to
+match the longest possible string. For example, when matching
+@samp{(fooq|foo)*(qbarquux|bar)} against @samp{fooqbarquux}, it cannot
+take, say, the first (``depth-first'') combination it could match, since
+then it would be content to match just @samp{fooqbar}.
+
+@comment xx something about leftmost-longest
+
+
+@node List Operators, Grouping Operators, Alternation Operator, Common Operators
+@section List Operators (@code{[} @dots{} @code{]} and @code{[^} @dots{} @code{]})
+
+@cindex matching list
+@cindex @samp{[}
+@cindex @samp{]}
+@cindex @samp{^}
+@cindex @samp{-}
+@cindex @samp{\}
+@cindex @samp{[^}
+@cindex nonmatching list
+@cindex matching newline
+@cindex bracket expression
+
+@dfn{Lists}, also called @dfn{bracket expressions}, are a set of one or
+more items. An @dfn{item} is a character,
+@ignore
+(These get added when they get implemented.)
+a collating symbol, an equivalence class expression,
+@end ignore
+a character class expression, or a range expression. The syntax bits
+affect which kinds of items you can put in a list. We explain the last
+two items in subsections below. Empty lists are invalid.
+
+A @dfn{matching list} matches a single character represented by one of
+the list items. You form a matching list by enclosing one or more items
+within an @dfn{open-matching-list operator} (represented by @samp{[})
+and a @dfn{close-list operator} (represented by @samp{]}).
+
+For example, @samp{[ab]} matches either @samp{a} or @samp{b}.
+@samp{[ad]*} matches the empty string and any string composed of just
+@samp{a}s and @samp{d}s in any order. Regex considers invalid a regular
+expression with a @samp{[} but no matching
+@samp{]}.
+
+@dfn{Nonmatching lists} are similar to matching lists except that they
+match a single character @emph{not} represented by one of the list
+items. You use an @dfn{open-nonmatching-list operator} (represented by
+@samp{[^}@footnote{Regex therefore doesn't consider the @samp{^} to be
+the first character in the list. If you put a @samp{^} character first
+in (what you think is) a matching list, you'll turn it into a
+nonmatching list.}) instead of an open-matching-list operator to start a
+nonmatching list.
+
+For example, @samp{[^ab]} matches any character except @samp{a} or
+@samp{b}.
+
+If the @code{posix_newline} field in the pattern buffer (@pxref{GNU
+Pattern Buffers} is set, then nonmatching lists do not match a newline.
+
+Most characters lose any special meaning inside a list. The special
+characters inside a list follow.
+
+@table @samp
+@item ]
+ends the list if it's not the first list item. So, if you want to make
+the @samp{]} character a list item, you must put it first.
+
+@item \
+quotes the next character if the syntax bit @code{RE_BACKSLASH_ESCAPE_IN_LISTS} is
+set.
+
+@ignore
+Put these in if they get implemented.
+
+@item [.
+represents the open-collating-symbol operator (@pxref{Collating Symbol
+Operators}).
+
+@item .]
+represents the close-collating-symbol operator.
+
+@item [=
+represents the open-equivalence-class operator (@pxref{Equivalence Class
+Operators}).
+
+@item =]
+represents the close-equivalence-class operator.
+
+@end ignore
+
+@item [:
+represents the open-character-class operator (@pxref{Character Class
+Operators}) if the syntax bit @code{RE_CHAR_CLASSES} is set and what
+follows is a valid character class expression.
+
+@item :]
+represents the close-character-class operator if the syntax bit
+@code{RE_CHAR_CLASSES} is set and what precedes it is an
+open-character-class operator followed by a valid character class name.
+
+@item -
+represents the range operator (@pxref{Range Operator}) if it's
+not first or last in a list or the ending point of a range.
+
+@end table
+
+@noindent
+All other characters are ordinary. For example, @samp{[.*]} matches
+@samp{.} and @samp{*}.
+
+@menu
+* Character Class Operators:: [:class:]
+* Range Operator:: start-end
+@end menu
+
+@ignore
+(If collating symbols and equivalence class expressions get implemented,
+then add this.)
+
+node Collating Symbol Operators
+subsubsection Collating Symbol Operators (@code{[.} @dots{} @code{.]})
+
+If the syntax bit @code{XX} is set, then you can represent
+collating symbols inside lists. You form a @dfn{collating symbol} by
+putting a collating element between an @dfn{open-collating-symbol
+operator} and an @dfn{close-collating-symbol operator}. @samp{[.}
+represents the open-collating-symbol operator and @samp{.]} represents
+the close-collating-symbol operator. For example, if @samp{ll} is a
+collating element, then @samp{[[.ll.]]} would match @samp{ll}.
+
+node Equivalence Class Operators
+subsubsection Equivalence Class Operators (@code{[=} @dots{} @code{=]})
+@cindex equivalence class expression in regex
+@cindex @samp{[=} in regex
+@cindex @samp{=]} in regex
+
+If the syntax bit @code{XX} is set, then Regex recognizes equivalence class
+expressions inside lists. A @dfn{equivalence class expression} is a set
+of collating elements which all belong to the same equivalence class.
+You form an equivalence class expression by putting a collating
+element between an @dfn{open-equivalence-class operator} and a
+@dfn{close-equivalence-class operator}. @samp{[=} represents the
+open-equivalence-class operator and @samp{=]} represents the
+close-equivalence-class operator. For example, if @samp{a} and @samp{A}
+were an equivalence class, then both @samp{[[=a=]]} and @samp{[[=A=]]}
+would match both @samp{a} and @samp{A}. If the collating element in an
+equivalence class expression isn't part of an equivalence class, then
+the matcher considers the equivalence class expression to be a collating
+symbol.
+
+@end ignore
+
+@node Character Class Operators, Range Operator, , List Operators
+@subsection Character Class Operators (@code{[:} @dots{} @code{:]})
+
+@cindex character classes
+@cindex @samp{[:} in regex
+@cindex @samp{:]} in regex
+
+If the syntax bit @code{RE_CHARACTER_CLASSES} is set, then Regex
+recognizes character class expressions inside lists. A @dfn{character
+class expression} matches one character from a given class. You form a
+character class expression by putting a character class name between an
+@dfn{open-character-class operator} (represented by @samp{[:}) and a
+@dfn{close-character-class operator} (represented by @samp{:]}). The
+character class names and their meanings are:
+
+@table @code
+
+@item alnum
+letters and digits
+
+@item alpha
+letters
+
+@item blank
+system-dependent; for @sc{gnu}, a space or tab
+
+@item cntrl
+control characters (in the @sc{ascii} encoding, code 0177 and codes
+less than 040)
+
+@item digit
+digits
+
+@item graph
+same as @code{print} except omits space
+
+@item lower
+lowercase letters
+
+@item print
+printable characters (in the @sc{ascii} encoding, space
+tilde---codes 040 through 0176)
+
+@item punct
+neither control nor alphanumeric characters
+
+@item space
+space, carriage return, newline, vertical tab, and form feed
+
+@item upper
+uppercase letters
+
+@item xdigit
+hexadecimal digits: @code{0}--@code{9}, @code{a}--@code{f}, @code{A}--@code{F}
+
+@end table
+
+@noindent
+These correspond to the definitions in the C library's @file{<ctype.h>}
+facility. For example, @samp{[:alpha:]} corresponds to the standard
+facility @code{isalpha}. Regex recognizes character class expressions
+only inside of lists; so @samp{[[:alpha:]]} matches any letter, but
+@samp{[:alpha:]} outside of a bracket expression and not followed by a
+repetition operator matches just itself.
+
+@node Range Operator, , Character Class Operators, List Operators
+@subsection The Range Operator (@code{-})
+
+Regex recognizes @dfn{range expressions} inside a list. They represent
+those characters
+that fall between two elements in the current collating sequence. You
+form a range expression by putting a @dfn{range operator} between two
+@ignore
+(If these get implemented, then substitute this for ``characters.'')
+of any of the following: characters, collating elements, collating symbols,
+and equivalence class expressions. The starting point of the range and
+the ending point of the range don't have to be the same kind of item,
+e.g., the starting point could be a collating element and the ending
+point could be an equivalence class expression. If a range's ending
+point is an equivalence class, then all the collating elements in that
+class will be in the range.
+@end ignore
+characters.@footnote{You can't use a character class for the starting
+or ending point of a range, since a character class is not a single
+character.} @samp{-} represents the range operator. For example,
+@samp{a-f} within a list represents all the characters from @samp{a}
+through @samp{f}
+inclusively.
+
+If the syntax bit @code{RE_NO_EMPTY_RANGES} is set, then if the range's
+ending point collates less than its starting point, the range (and the
+regular expression containing it) is invalid. For example, the regular
+expression @samp{[z-a]} would be invalid. If this bit isn't set, then
+Regex considers such a range to be empty.
+
+Since @samp{-} represents the range operator, if you want to make a
+@samp{-} character itself
+a list item, you must do one of the following:
+
+@itemize @bullet
+@item
+Put the @samp{-} either first or last in the list.
+
+@item
+Include a range whose starting point collates strictly lower than
+@samp{-} and whose ending point collates equal or higher. Unless a
+range is the first item in a list, a @samp{-} can't be its starting
+point, but @emph{can} be its ending point. That is because Regex
+considers @samp{-} to be the range operator unless it is preceded by
+another @samp{-}. For example, in the @sc{ascii} encoding, @samp{)},
+@samp{*}, @samp{+}, @samp{,}, @samp{-}, @samp{.}, and @samp{/} are
+contiguous characters in the collating sequence. You might think that
+@samp{[)-+--/]} has two ranges: @samp{)-+} and @samp{--/}. Rather, it
+has the ranges @samp{)-+} and @samp{+--}, plus the character @samp{/}, so
+it matches, e.g., @samp{,}, not @samp{.}.
+
+@item
+Put a range whose starting point is @samp{-} first in the list.
+
+@end itemize
+
+For example, @samp{[-a-z]} matches a lowercase letter or a hyphen (in
+English, in @sc{ascii}).
+
+
+@node Grouping Operators, Back-reference Operator, List Operators, Common Operators
+@section Grouping Operators (@code{(} @dots{} @code{)} or @code{\(} @dots{} @code{\)})
+
+@kindex (
+@kindex )
+@kindex \(
+@kindex \)
+@cindex grouping
+@cindex subexpressions
+@cindex parenthesizing
+
+A @dfn{group}, also known as a @dfn{subexpression}, consists of an
+@dfn{open-group operator}, any number of other operators, and a
+@dfn{close-group operator}. Regex treats this sequence as a unit, just
+as mathematics and programming languages treat a parenthesized
+expression as a unit.
+
+Therefore, using @dfn{groups}, you can:
+
+@itemize @bullet
+@item
+delimit the argument(s) to an alternation operator (@pxref{Alternation
+Operator}) or a repetition operator (@pxref{Repetition
+Operators}).
+
+@item
+keep track of the indices of the substring that matched a given group.
+@xref{Using Registers}, for a precise explanation.
+This lets you:
+
+@itemize @bullet
+@item
+use the back-reference operator (@pxref{Back-reference Operator}).
+
+@item
+use registers (@pxref{Using Registers}).
+
+@end itemize
+
+@end itemize
+
+If the syntax bit @code{RE_NO_BK_PARENS} is set, then @samp{(} represents
+the open-group operator and @samp{)} represents the
+close-group operator; otherwise, @samp{\(} and @samp{\)} do.
+
+If the syntax bit @code{RE_UNMATCHED_RIGHT_PAREN_ORD} is set and a
+close-group operator has no matching open-group operator, then Regex
+considers it to match @samp{)}.
+
+
+@node Back-reference Operator, Anchoring Operators, Grouping Operators, Common Operators
+@section The Back-reference Operator (@dfn{\}@var{digit})
+
+@cindex back references
+
+If the syntax bit @code{RE_NO_BK_REF} isn't set, then Regex recognizes
+back references. A back reference matches a specified preceding group.
+The back reference operator is represented by @samp{\@var{digit}}
+anywhere after the end of a regular expression's @w{@var{digit}-th}
+group (@pxref{Grouping Operators}).
+
+@var{digit} must be between @samp{1} and @samp{9}. The matcher assigns
+numbers 1 through 9 to the first nine groups it encounters. By using
+one of @samp{\1} through @samp{\9} after the corresponding group's
+close-group operator, you can match a substring identical to the
+one that the group does.
+
+Back references match according to the following (in all examples below,
+@samp{(} represents the open-group, @samp{)} the close-group, @samp{@{}
+the open-interval and @samp{@}} the close-interval operator):
+
+@itemize @bullet
+@item
+If the group matches a substring, the back reference matches an
+identical substring. For example, @samp{(a)\1} matches @samp{aa} and
+@samp{(bana)na\1bo\1} matches @samp{bananabanabobana}. Likewise,
+@samp{(.*)\1} matches any (newline-free if the syntax bit
+@code{RE_DOT_NEWLINE} isn't set) string that is composed of two
+identical halves; the @samp{(.*)} matches the first half and the
+@samp{\1} matches the second half.
+
+@item
+If the group matches more than once (as it might if followed
+by, e.g., a repetition operator), then the back reference matches the
+substring the group @emph{last} matched. For example,
+@samp{((a*)b)*\1\2} matches @samp{aabababa}; first @w{group 1} (the
+outer one) matches @samp{aab} and @w{group 2} (the inner one) matches
+@samp{aa}. Then @w{group 1} matches @samp{ab} and @w{group 2} matches
+@samp{a}. So, @samp{\1} matches @samp{ab} and @samp{\2} matches
+@samp{a}.
+
+@item
+If the group doesn't participate in a match, i.e., it is part of an
+alternative not taken or a repetition operator allows zero repetitions
+of it, then the back reference makes the whole match fail. For example,
+@samp{(one()|two())-and-(three\2|four\3)} matches @samp{one-and-three}
+and @samp{two-and-four}, but not @samp{one-and-four} or
+@samp{two-and-three}. For example, if the pattern matches
+@samp{one-and-}, then its @w{group 2} matches the empty string and its
+@w{group 3} doesn't participate in the match. So, if it then matches
+@samp{four}, then when it tries to back reference @w{group 3}---which it
+will attempt to do because @samp{\3} follows the @samp{four}---the match
+will fail because @w{group 3} didn't participate in the match.
+
+@end itemize
+
+You can use a back reference as an argument to a repetition operator. For
+example, @samp{(a(b))\2*} matches @samp{a} followed by two or more
+@samp{b}s. Similarly, @samp{(a(b))\2@{3@}} matches @samp{abbbb}.
+
+If there is no preceding @w{@var{digit}-th} subexpression, the regular
+expression is invalid.
+
+
+@node Anchoring Operators, , Back-reference Operator, Common Operators
+@section Anchoring Operators
+
+@cindex anchoring
+@cindex regexp anchoring
+
+These operators can constrain a pattern to match only at the beginning or
+end of the entire string or at the beginning or end of a line.
+
+@menu
+* Match-beginning-of-line Operator:: ^
+* Match-end-of-line Operator:: $
+@end menu
+
+
+@node Match-beginning-of-line Operator, Match-end-of-line Operator, , Anchoring Operators
+@subsection The Match-beginning-of-line Operator (@code{^})
+
+@kindex ^
+@cindex beginning-of-line operator
+@cindex anchors
+
+This operator can match the empty string either at the beginning of the
+string or after a newline character. Thus, it is said to @dfn{anchor}
+the pattern to the beginning of a line.
+
+In the cases following, @samp{^} represents this operator. (Otherwise,
+@samp{^} is ordinary.)
+
+@itemize @bullet
+
+@item
+It (the @samp{^}) is first in the pattern, as in @samp{^foo}.
+
+@cnindex RE_CONTEXT_INDEP_ANCHORS @r{(and @samp{^})}
+@item
+The syntax bit @code{RE_CONTEXT_INDEP_ANCHORS} is set, and it is outside
+a bracket expression.
+
+@cindex open-group operator and @samp{^}
+@cindex alternation operator and @samp{^}
+@item
+It follows an open-group or alternation operator, as in @samp{a\(^b\)}
+and @samp{a\|^b}. @xref{Grouping Operators}, and @ref{Alternation
+Operator}.
+
+@end itemize
+
+These rules imply that some valid patterns containing @samp{^} cannot be
+matched; for example, @samp{foo^bar} if @code{RE_CONTEXT_INDEP_ANCHORS}
+is set.
+
+@vindex not_bol @r{field in pattern buffer}
+If the @code{not_bol} field is set in the pattern buffer (@pxref{GNU
+Pattern Buffers}), then @samp{^} fails to match at the beginning of the
+string. @xref{POSIX Matching}, for when you might find this useful.
+
+@vindex newline_anchor @r{field in pattern buffer}
+If the @code{newline_anchor} field is set in the pattern buffer, then
+@samp{^} fails to match after a newline. This is useful when you do not
+regard the string to be matched as broken into lines.
+
+
+@node Match-end-of-line Operator, , Match-beginning-of-line Operator, Anchoring Operators
+@subsection The Match-end-of-line Operator (@code{$})
+
+@kindex $
+@cindex end-of-line operator
+@cindex anchors
+
+This operator can match the empty string either at the end of
+the string or before a newline character in the string. Thus, it is
+said to @dfn{anchor} the pattern to the end of a line.
+
+It is always represented by @samp{$}. For example, @samp{foo$} usually
+matches, e.g., @samp{foo} and, e.g., the first three characters of
+@samp{foo\nbar}.
+
+Its interaction with the syntax bits and pattern buffer fields is
+exactly the dual of @samp{^}'s; see the previous section. (That is,
+``beginning'' becomes ``end'', ``next'' becomes ``previous'', and
+``after'' becomes ``before''.)
+
+
+@node GNU Operators, GNU Emacs Operators, Common Operators, Top
+@chapter GNU Operators
+
+Following are operators that @sc{gnu} defines (and @sc{posix} doesn't).
+
+@menu
+* Word Operators::
+* Buffer Operators::
+@end menu
+
+@node Word Operators, Buffer Operators, , GNU Operators
+@section Word Operators
+
+The operators in this section require Regex to recognize parts of words.
+Regex uses a syntax table to determine whether or not a character is
+part of a word, i.e., whether or not it is @dfn{word-constituent}.
+
+@menu
+* Non-Emacs Syntax Tables::
+* Match-word-boundary Operator:: \b
+* Match-within-word Operator:: \B
+* Match-beginning-of-word Operator:: \<
+* Match-end-of-word Operator:: \>
+* Match-word-constituent Operator:: \w
+* Match-non-word-constituent Operator:: \W
+@end menu
+
+@node Non-Emacs Syntax Tables, Match-word-boundary Operator, , Word Operators
+@subsection Non-Emacs Syntax Tables
+
+A @dfn{syntax table} is an array indexed by the characters in your
+character set. In the @sc{ascii} encoding, therefore, a syntax table
+has 256 elements. Regex always uses a @code{char *} variable
+@code{re_syntax_table} as its syntax table. In some cases, it
+initializes this variable and in others it expects you to initialize it.
+
+@itemize @bullet
+@item
+If Regex is compiled with the preprocessor symbols @code{emacs} and
+@code{SYNTAX_TABLE} both undefined, then Regex allocates
+@code{re_syntax_table} and initializes an element @var{i} either to
+@code{Sword} (which it defines) if @var{i} is a letter, number, or
+@samp{_}, or to zero if it's not.
+
+@item
+If Regex is compiled with @code{emacs} undefined but @code{SYNTAX_TABLE}
+defined, then Regex expects you to define a @code{char *} variable
+@code{re_syntax_table} to be a valid syntax table.
+
+@item
+@xref{Emacs Syntax Tables}, for what happens when Regex is compiled with
+the preprocessor symbol @code{emacs} defined.
+
+@end itemize
+
+@node Match-word-boundary Operator, Match-within-word Operator, Non-Emacs Syntax Tables, Word Operators
+@subsection The Match-word-boundary Operator (@code{\b})
+
+@cindex @samp{\b}
+@cindex word boundaries, matching
+
+This operator (represented by @samp{\b}) matches the empty string at
+either the beginning or the end of a word. For example, @samp{\brat\b}
+matches the separate word @samp{rat}.
+
+@node Match-within-word Operator, Match-beginning-of-word Operator, Match-word-boundary Operator, Word Operators
+@subsection The Match-within-word Operator (@code{\B})
+
+@cindex @samp{\B}
+
+This operator (represented by @samp{\B}) matches the empty string within
+a word. For example, @samp{c\Brat\Be} matches @samp{crate}, but
+@samp{dirty \Brat} doesn't match @samp{dirty rat}.
+
+@node Match-beginning-of-word Operator, Match-end-of-word Operator, Match-within-word Operator, Word Operators
+@subsection The Match-beginning-of-word Operator (@code{\<})
+
+@cindex @samp{\<}
+
+This operator (represented by @samp{\<}) matches the empty string at the
+beginning of a word.
+
+@node Match-end-of-word Operator, Match-word-constituent Operator, Match-beginning-of-word Operator, Word Operators
+@subsection The Match-end-of-word Operator (@code{\>})
+
+@cindex @samp{\>}
+
+This operator (represented by @samp{\>}) matches the empty string at the
+end of a word.
+
+@node Match-word-constituent Operator, Match-non-word-constituent Operator, Match-end-of-word Operator, Word Operators
+@subsection The Match-word-constituent Operator (@code{\w})
+
+@cindex @samp{\w}
+
+This operator (represented by @samp{\w}) matches any word-constituent
+character.
+
+@node Match-non-word-constituent Operator, , Match-word-constituent Operator, Word Operators
+@subsection The Match-non-word-constituent Operator (@code{\W})
+
+@cindex @samp{\W}
+
+This operator (represented by @samp{\W}) matches any character that is
+not word-constituent.
+
+
+@node Buffer Operators, , Word Operators, GNU Operators
+@section Buffer Operators
+
+Following are operators which work on buffers. In Emacs, a @dfn{buffer}
+is, naturally, an Emacs buffer. For other programs, Regex considers the
+entire string to be matched as the buffer.
+
+@menu
+* Match-beginning-of-buffer Operator:: \`
+* Match-end-of-buffer Operator:: \'
+@end menu
+
+
+@node Match-beginning-of-buffer Operator, Match-end-of-buffer Operator, , Buffer Operators
+@subsection The Match-beginning-of-buffer Operator (@code{\`})
+
+@cindex @samp{\`}
+
+This operator (represented by @samp{\`}) matches the empty string at the
+beginning of the buffer.
+
+@node Match-end-of-buffer Operator, , Match-beginning-of-buffer Operator, Buffer Operators
+@subsection The Match-end-of-buffer Operator (@code{\'})
+
+@cindex @samp{\'}
+
+This operator (represented by @samp{\'}) matches the empty string at the
+end of the buffer.
+
+
+@node GNU Emacs Operators, What Gets Matched?, GNU Operators, Top
+@chapter GNU Emacs Operators
+
+Following are operators that @sc{gnu} defines (and @sc{posix} doesn't)
+that you can use only when Regex is compiled with the preprocessor
+symbol @code{emacs} defined.
+
+@menu
+* Syntactic Class Operators::
+@end menu
+
+
+@node Syntactic Class Operators, , , GNU Emacs Operators
+@section Syntactic Class Operators
+
+The operators in this section require Regex to recognize the syntactic
+classes of characters. Regex uses a syntax table to determine this.
+
+@menu
+* Emacs Syntax Tables::
+* Match-syntactic-class Operator:: \sCLASS
+* Match-not-syntactic-class Operator:: \SCLASS
+@end menu
+
+@node Emacs Syntax Tables, Match-syntactic-class Operator, , Syntactic Class Operators
+@subsection Emacs Syntax Tables
+
+A @dfn{syntax table} is an array indexed by the characters in your
+character set. In the @sc{ascii} encoding, therefore, a syntax table
+has 256 elements.
+
+If Regex is compiled with the preprocessor symbol @code{emacs} defined,
+then Regex expects you to define and initialize the variable
+@code{re_syntax_table} to be an Emacs syntax table. Emacs' syntax
+tables are more complicated than Regex's own (@pxref{Non-Emacs Syntax
+Tables}). @xref{Syntax, , Syntax, emacs, The GNU Emacs User's Manual},
+for a description of Emacs' syntax tables.
+
+@node Match-syntactic-class Operator, Match-not-syntactic-class Operator, Emacs Syntax Tables, Syntactic Class Operators
+@subsection The Match-syntactic-class Operator (@code{\s}@var{class})
+
+@cindex @samp{\s}
+
+This operator matches any character whose syntactic class is represented
+by a specified character. @samp{\s@var{class}} represents this operator
+where @var{class} is the character representing the syntactic class you
+want. For example, @samp{w} represents the syntactic
+class of word-constituent characters, so @samp{\sw} matches any
+word-constituent character.
+
+@node Match-not-syntactic-class Operator, , Match-syntactic-class Operator, Syntactic Class Operators
+@subsection The Match-not-syntactic-class Operator (@code{\S}@var{class})
+
+@cindex @samp{\S}
+
+This operator is similar to the match-syntactic-class operator except
+that it matches any character whose syntactic class is @emph{not}
+represented by the specified character. @samp{\S@var{class}} represents
+this operator. For example, @samp{w} represents the syntactic class of
+word-constituent characters, so @samp{\Sw} matches any character that is
+not word-constituent.
+
+
+@node What Gets Matched?, Programming with Regex, GNU Emacs Operators, Top
+@chapter What Gets Matched?
+
+Regex usually matches strings according to the ``leftmost longest''
+rule; that is, it chooses the longest of the leftmost matches. This
+does not mean that for a regular expression containing subexpressions
+that it simply chooses the longest match for each subexpression, left to
+right; the overall match must also be the longest possible one.
+
+For example, @samp{(ac*)(c*d[ac]*)\1} matches @samp{acdacaaa}, not
+@samp{acdac}, as it would if it were to choose the longest match for the
+first subexpression.
+
+
+@node Programming with Regex, Copying, What Gets Matched?, Top
+@chapter Programming with Regex
+
+Here we describe how you use the Regex data structures and functions in
+C programs. Regex has three interfaces: one designed for @sc{gnu}, one
+compatible with @sc{posix} and one compatible with Berkeley @sc{unix}.
+
+@menu
+* GNU Regex Functions::
+* POSIX Regex Functions::
+* BSD Regex Functions::
+@end menu
+
+
+@node GNU Regex Functions, POSIX Regex Functions, , Programming with Regex
+@section GNU Regex Functions
+
+If you're writing code that doesn't need to be compatible with either
+@sc{posix} or Berkeley @sc{unix}, you can use these functions. They
+provide more options than the other interfaces.
+
+@menu
+* GNU Pattern Buffers:: The re_pattern_buffer type.
+* GNU Regular Expression Compiling:: re_compile_pattern ()
+* GNU Matching:: re_match ()
+* GNU Searching:: re_search ()
+* Matching/Searching with Split Data:: re_match_2 (), re_search_2 ()
+* Searching with Fastmaps:: re_compile_fastmap ()
+* GNU Translate Tables:: The `translate' field.
+* Using Registers:: The re_registers type and related fns.
+* Freeing GNU Pattern Buffers:: regfree ()
+@end menu
+
+
+@node GNU Pattern Buffers, GNU Regular Expression Compiling, , GNU Regex Functions
+@subsection GNU Pattern Buffers
+
+@cindex pattern buffer, definition of
+@tindex re_pattern_buffer @r{definition}
+@tindex struct re_pattern_buffer @r{definition}
+
+To compile, match, or search for a given regular expression, you must
+supply a pattern buffer. A @dfn{pattern buffer} holds one compiled
+regular expression.@footnote{Regular expressions are also referred to as
+``patterns,'' hence the name ``pattern buffer.''}
+
+You can have several different pattern buffers simultaneously, each
+holding a compiled pattern for a different regular expression.
+
+@file{regex.h} defines the pattern buffer @code{struct} as follows:
+
+@example
+[[[ pattern_buffer ]]]
+@end example
+
+
+@node GNU Regular Expression Compiling, GNU Matching, GNU Pattern Buffers, GNU Regex Functions
+@subsection GNU Regular Expression Compiling
+
+In @sc{gnu}, you can both match and search for a given regular
+expression. To do either, you must first compile it in a pattern buffer
+(@pxref{GNU Pattern Buffers}).
+
+@cindex syntax initialization
+@vindex re_syntax_options @r{initialization}
+Regular expressions match according to the syntax with which they were
+compiled; with @sc{gnu}, you indicate what syntax you want by setting
+the variable @code{re_syntax_options} (declared in @file{regex.h} and
+defined in @file{regex.c}) before calling the compiling function,
+@code{re_compile_pattern} (see below). @xref{Syntax Bits}, and
+@ref{Predefined Syntaxes}.
+
+You can change the value of @code{re_syntax_options} at any time.
+Usually, however, you set its value once and then never change it.
+
+@cindex pattern buffer initialization
+@code{re_compile_pattern} takes a pattern buffer as an argument. You
+must initialize the following fields:
+
+@table @code
+
+@item translate @r{initialization}
+
+@item translate
+@vindex translate @r{initialization}
+Initialize this to point to a translate table if you want one, or to
+zero if you don't. We explain translate tables in @ref{GNU Translate
+Tables}.
+
+@item fastmap
+@vindex fastmap @r{initialization}
+Initialize this to nonzero if you want a fastmap, or to zero if you
+don't.
+
+@item buffer
+@itemx allocated
+@vindex buffer @r{initialization}
+@vindex allocated @r{initialization}
+@findex malloc
+If you want @code{re_compile_pattern} to allocate memory for the
+compiled pattern, set both of these to zero. If you have an existing
+block of memory (allocated with @code{malloc}) you want Regex to use,
+set @code{buffer} to its address and @code{allocated} to its size (in
+bytes).
+
+@code{re_compile_pattern} uses @code{realloc} to extend the space for
+the compiled pattern as necessary.
+
+@end table
+
+To compile a pattern buffer, use:
+
+@findex re_compile_pattern
+@example
+char *
+re_compile_pattern (const char *@var{regex}, const int @var{regex_size},
+ struct re_pattern_buffer *@var{pattern_buffer})
+@end example
+
+@noindent
+@var{regex} is the regular expression's address, @var{regex_size} is its
+length, and @var{pattern_buffer} is the pattern buffer's address.
+
+If @code{re_compile_pattern} successfully compiles the regular
+expression, it returns zero and sets @code{*@var{pattern_buffer}} to the
+compiled pattern. It sets the pattern buffer's fields as follows:
+
+@table @code
+@item buffer
+@vindex buffer @r{field, set by @code{re_compile_pattern}}
+to the compiled pattern.
+
+@item used
+@vindex used @r{field, set by @code{re_compile_pattern}}
+to the number of bytes the compiled pattern in @code{buffer} occupies.
+
+@item syntax
+@vindex syntax @r{field, set by @code{re_compile_pattern}}
+to the current value of @code{re_syntax_options}.
+
+@item re_nsub
+@vindex re_nsub @r{field, set by @code{re_compile_pattern}}
+to the number of subexpressions in @var{regex}.
+
+@item fastmap_accurate
+@vindex fastmap_accurate @r{field, set by @code{re_compile_pattern}}
+to zero on the theory that the pattern you're compiling is different
+than the one previously compiled into @code{buffer}; in that case (since
+you can't make a fastmap without a compiled pattern),
+@code{fastmap} would either contain an incompatible fastmap, or nothing
+at all.
+
+@c xx what else?
+@end table
+
+If @code{re_compile_pattern} can't compile @var{regex}, it returns an
+error string corresponding to one of the errors listed in @ref{POSIX
+Regular Expression Compiling}.
+
+
+@node GNU Matching, GNU Searching, GNU Regular Expression Compiling, GNU Regex Functions
+@subsection GNU Matching
+
+@cindex matching with GNU functions
+
+Matching the @sc{gnu} way means trying to match as much of a string as
+possible starting at a position within it you specify. Once you've compiled
+a pattern into a pattern buffer (@pxref{GNU Regular Expression
+Compiling}), you can ask the matcher to match that pattern against a
+string using:
+
+@findex re_match
+@example
+int
+re_match (struct re_pattern_buffer *@var{pattern_buffer},
+ const char *@var{string}, const int @var{size},
+ const int @var{start}, struct re_registers *@var{regs})
+@end example
+
+@noindent
+@var{pattern_buffer} is the address of a pattern buffer containing a
+compiled pattern. @var{string} is the string you want to match; it can
+contain newline and null characters. @var{size} is the length of that
+string. @var{start} is the string index at which you want to
+begin matching; the first character of @var{string} is at index zero.
+@xref{Using Registers}, for a explanation of @var{regs}; you can safely
+pass zero.
+
+@code{re_match} matches the regular expression in @var{pattern_buffer}
+against the string @var{string} according to the syntax in
+@var{pattern_buffers}'s @code{syntax} field. (@xref{GNU Regular
+Expression Compiling}, for how to set it.) The function returns
+@math{-1} if the compiled pattern does not match any part of
+@var{string} and @math{-2} if an internal error happens; otherwise, it
+returns how many (possibly zero) characters of @var{string} the pattern
+matched.
+
+An example: suppose @var{pattern_buffer} points to a pattern buffer
+containing the compiled pattern for @samp{a*}, and @var{string} points
+to @samp{aaaaab} (whereupon @var{size} should be 6). Then if @var{start}
+is 2, @code{re_match} returns 3, i.e., @samp{a*} would have matched the
+last three @samp{a}s in @var{string}. If @var{start} is 0,
+@code{re_match} returns 5, i.e., @samp{a*} would have matched all the
+@samp{a}s in @var{string}. If @var{start} is either 5 or 6, it returns
+zero.
+
+If @var{start} is not between zero and @var{size}, then
+@code{re_match} returns @math{-1}.
+
+
+@node GNU Searching, Matching/Searching with Split Data, GNU Matching, GNU Regex Functions
+@subsection GNU Searching
+
+@cindex searching with GNU functions
+
+@dfn{Searching} means trying to match starting at successive positions
+within a string. The function @code{re_search} does this.
+
+Before calling @code{re_search}, you must compile your regular
+expression. @xref{GNU Regular Expression Compiling}.
+
+Here is the function declaration:
+
+@findex re_search
+@example
+int
+re_search (struct re_pattern_buffer *@var{pattern_buffer},
+ const char *@var{string}, const int @var{size},
+ const int @var{start}, const int @var{range},
+ struct re_registers *@var{regs})
+@end example
+
+@noindent
+@vindex start @r{argument to @code{re_search}}
+@vindex range @r{argument to @code{re_search}}
+whose arguments are the same as those to @code{re_match} (@pxref{GNU
+Matching}) except that the two arguments @var{start} and @var{range}
+replace @code{re_match}'s argument @var{start}.
+
+If @var{range} is positive, then @code{re_search} attempts a match
+starting first at index @var{start}, then at @math{@var{start} + 1} if
+that fails, and so on, up to @math{@var{start} + @var{range}}; if
+@var{range} is negative, then it attempts a match starting first at
+index @var{start}, then at @math{@var{start} -1} if that fails, and so
+on.
+
+If @var{start} is not between zero and @var{size}, then @code{re_search}
+returns @math{-1}. When @var{range} is positive, @code{re_search}
+adjusts @var{range} so that @math{@var{start} + @var{range} - 1} is
+between zero and @var{size}, if necessary; that way it won't search
+outside of @var{string}. Similarly, when @var{range} is negative,
+@code{re_search} adjusts @var{range} so that @math{@var{start} +
+@var{range} + 1} is between zero and @var{size}, if necessary.
+
+If the @code{fastmap} field of @var{pattern_buffer} is zero,
+@code{re_search} matches starting at consecutive positions; otherwise,
+it uses @code{fastmap} to make the search more efficient.
+@xref{Searching with Fastmaps}.
+
+If no match is found, @code{re_search} returns @math{-1}. If
+a match is found, it returns the index where the match began. If an
+internal error happens, it returns @math{-2}.
+
+
+@node Matching/Searching with Split Data, Searching with Fastmaps, GNU Searching, GNU Regex Functions
+@subsection Matching and Searching with Split Data
+
+Using the functions @code{re_match_2} and @code{re_search_2}, you can
+match or search in data that is divided into two strings.
+
+The function:
+
+@findex re_match_2
+@example
+int
+re_match_2 (struct re_pattern_buffer *@var{buffer},
+ const char *@var{string1}, const int @var{size1},
+ const char *@var{string2}, const int @var{size2},
+ const int @var{start},
+ struct re_registers *@var{regs},
+ const int @var{stop})
+@end example
+
+@noindent
+is similar to @code{re_match} (@pxref{GNU Matching}) except that you
+pass @emph{two} data strings and sizes, and an index @var{stop} beyond
+which you don't want the matcher to try matching. As with
+@code{re_match}, if it succeeds, @code{re_match_2} returns how many
+characters of @var{string} it matched. Regard @var{string1} and
+@var{string2} as concatenated when you set the arguments @var{start} and
+@var{stop} and use the contents of @var{regs}; @code{re_match_2} never
+returns a value larger than @math{@var{size1} + @var{size2}}.
+
+The function:
+
+@findex re_search_2
+@example
+int
+re_search_2 (struct re_pattern_buffer *@var{buffer},
+ const char *@var{string1}, const int @var{size1},
+ const char *@var{string2}, const int @var{size2},
+ const int @var{start}, const int @var{range},
+ struct re_registers *@var{regs},
+ const int @var{stop})
+@end example
+
+@noindent
+is similarly related to @code{re_search}.
+
+
+@node Searching with Fastmaps, GNU Translate Tables, Matching/Searching with Split Data, GNU Regex Functions
+@subsection Searching with Fastmaps
+
+@cindex fastmaps
+If you're searching through a long string, you should use a fastmap.
+Without one, the searcher tries to match at consecutive positions in the
+string. Generally, most of the characters in the string could not start
+a match. It takes much longer to try matching at a given position in the
+string than it does to check in a table whether or not the character at
+that position could start a match. A @dfn{fastmap} is such a table.
+
+More specifically, a fastmap is an array indexed by the characters in
+your character set. Under the @sc{ascii} encoding, therefore, a fastmap
+has 256 elements. If you want the searcher to use a fastmap with a
+given pattern buffer, you must allocate the array and assign the array's
+address to the pattern buffer's @code{fastmap} field. You either can
+compile the fastmap yourself or have @code{re_search} do it for you;
+when @code{fastmap} is nonzero, it automatically compiles a fastmap the
+first time you search using a particular compiled pattern.
+
+To compile a fastmap yourself, use:
+
+@findex re_compile_fastmap
+@example
+int
+re_compile_fastmap (struct re_pattern_buffer *@var{pattern_buffer})
+@end example
+
+@noindent
+@var{pattern_buffer} is the address of a pattern buffer. If the
+character @var{c} could start a match for the pattern,
+@code{re_compile_fastmap} makes
+@code{@var{pattern_buffer}->fastmap[@var{c}]} nonzero. It returns
+@math{0} if it can compile a fastmap and @math{-2} if there is an
+internal error. For example, if @samp{|} is the alternation operator
+and @var{pattern_buffer} holds the compiled pattern for @samp{a|b}, then
+@code{re_compile_fastmap} sets @code{fastmap['a']} and
+@code{fastmap['b']} (and no others).
+
+@code{re_search} uses a fastmap as it moves along in the string: it
+checks the string's characters until it finds one that's in the fastmap.
+Then it tries matching at that character. If the match fails, it
+repeats the process. So, by using a fastmap, @code{re_search} doesn't
+waste time trying to match at positions in the string that couldn't
+start a match.
+
+If you don't want @code{re_search} to use a fastmap,
+store zero in the @code{fastmap} field of the pattern buffer before
+calling @code{re_search}.
+
+Once you've initialized a pattern buffer's @code{fastmap} field, you
+need never do so again---even if you compile a new pattern in
+it---provided the way the field is set still reflects whether or not you
+want a fastmap. @code{re_search} will still either do nothing if
+@code{fastmap} is null or, if it isn't, compile a new fastmap for the
+new pattern.
+
+@node GNU Translate Tables, Using Registers, Searching with Fastmaps, GNU Regex Functions
+@subsection GNU Translate Tables
+
+If you set the @code{translate} field of a pattern buffer to a translate
+table, then the @sc{gnu} Regex functions to which you've passed that
+pattern buffer use it to apply a simple transformation
+to all the regular expression and string characters at which they look.
+
+A @dfn{translate table} is an array indexed by the characters in your
+character set. Under the @sc{ascii} encoding, therefore, a translate
+table has 256 elements. The array's elements are also characters in
+your character set. When the Regex functions see a character @var{c},
+they use @code{translate[@var{c}]} in its place, with one exception: the
+character after a @samp{\} is not translated. (This ensures that, the
+operators, e.g., @samp{\B} and @samp{\b}, are always distinguishable.)
+
+For example, a table that maps all lowercase letters to the
+corresponding uppercase ones would cause the matcher to ignore
+differences in case.@footnote{A table that maps all uppercase letters to
+the corresponding lowercase ones would work just as well for this
+purpose.} Such a table would map all characters except lowercase letters
+to themselves, and lowercase letters to the corresponding uppercase
+ones. Under the @sc{ascii} encoding, here's how you could initialize
+such a table (we'll call it @code{case_fold}):
+
+@example
+for (i = 0; i < 256; i++)
+ case_fold[i] = i;
+for (i = 'a'; i <= 'z'; i++)
+ case_fold[i] = i - ('a' - 'A');
+@end example
+
+You tell Regex to use a translate table on a given pattern buffer by
+assigning that table's address to the @code{translate} field of that
+buffer. If you don't want Regex to do any translation, put zero into
+this field. You'll get weird results if you change the table's contents
+anytime between compiling the pattern buffer, compiling its fastmap, and
+matching or searching with the pattern buffer.
+
+@node Using Registers, Freeing GNU Pattern Buffers, GNU Translate Tables, GNU Regex Functions
+@subsection Using Registers
+
+A group in a regular expression can match a (posssibly empty) substring
+of the string that regular expression as a whole matched. The matcher
+remembers the beginning and end of the substring matched by
+each group.
+
+To find out what they matched, pass a nonzero @var{regs} argument to a
+@sc{gnu} matching or searching function (@pxref{GNU Matching} and
+@ref{GNU Searching}), i.e., the address of a structure of this type, as
+defined in @file{regex.h}:
+
+@c We don't bother to include this directly from regex.h,
+@c since it changes so rarely.
+@example
+@tindex re_registers
+@vindex num_regs @r{in @code{struct re_registers}}
+@vindex start @r{in @code{struct re_registers}}
+@vindex end @r{in @code{struct re_registers}}
+struct re_registers
+@{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+@};
+@end example
+
+Except for (possibly) the @var{num_regs}'th element (see below), the
+@var{i}th element of the @code{start} and @code{end} arrays records
+information about the @var{i}th group in the pattern. (They're declared
+as C pointers, but this is only because not all C compilers accept
+zero-length arrays; conceptually, it is simplest to think of them as
+arrays.)
+
+The @code{start} and @code{end} arrays are allocated in various ways,
+depending on the value of the @code{regs_allocated}
+@vindex regs_allocated
+field in the pattern buffer passed to the matcher.
+
+The simplest and perhaps most useful is to let the matcher (re)allocate
+enough space to record information for all the groups in the regular
+expression. If @code{regs_allocated} is @code{REGS_UNALLOCATED},
+@vindex REGS_UNALLOCATED
+the matcher allocates @math{1 + @var{re_nsub}} (another field in the
+pattern buffer; @pxref{GNU Pattern Buffers}). The extra element is set
+to @math{-1}, and sets @code{regs_allocated} to @code{REGS_REALLOCATE}.
+@vindex REGS_REALLOCATE
+Then on subsequent calls with the same pattern buffer and @var{regs}
+arguments, the matcher reallocates more space if necessary.
+
+It would perhaps be more logical to make the @code{regs_allocated} field
+part of the @code{re_registers} structure, instead of part of the
+pattern buffer. But in that case the caller would be forced to
+initialize the structure before passing it. Much existing code doesn't
+do this initialization, and it's arguably better to avoid it anyway.
+
+@code{re_compile_pattern} sets @code{regs_allocated} to
+@code{REGS_UNALLOCATED},
+so if you use the GNU regular expression
+functions, you get this behavior by default.
+
+xx document re_set_registers
+
+@sc{posix}, on the other hand, requires a different interface: the
+caller is supposed to pass in a fixed-length array which the matcher
+fills. Therefore, if @code{regs_allocated} is @code{REGS_FIXED}
+@vindex REGS_FIXED
+the matcher simply fills that array.
+
+The following examples illustrate the information recorded in the
+@code{re_registers} structure. (In all of them, @samp{(} represents the
+open-group and @samp{)} the close-group operator. The first character
+in the string @var{string} is at index 0.)
+
+@c xx i'm not sure this is all true anymore.
+
+@itemize @bullet
+
+@item
+If the regular expression has an @w{@var{i}-th}
+group not contained within another group that matches a
+substring of @var{string}, then the function sets
+@code{@w{@var{regs}->}start[@var{i}]} to the index in @var{string} where
+the substring matched by the @w{@var{i}-th} group begins, and
+@code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that
+substring's end. The function sets @code{@w{@var{regs}->}start[0]} and
+@code{@w{@var{regs}->}end[0]} to analogous information about the entire
+pattern.
+
+For example, when you match @samp{((a)(b))} against @samp{ab}, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]}
+
+@item
+0 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]}
+
+@item
+0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]}
+
+@item
+1 in @code{@w{@var{regs}->}start[3]} and 2 in @code{@w{@var{regs}->}end[3]}
+@end itemize
+
+@item
+If a group matches more than once (as it might if followed by,
+e.g., a repetition operator), then the function reports the information
+about what the group @emph{last} matched.
+
+For example, when you match the pattern @samp{(a)*} against the string
+@samp{aa}, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 2 in @code{@w{@var{regs}->}end[0]}
+
+@item
+1 in @code{@w{@var{regs}->}start[1]} and 2 in @code{@w{@var{regs}->}end[1]}
+@end itemize
+
+@item
+If the @w{@var{i}-th} group does not participate in a
+successful match, e.g., it is an alternative not taken or a
+repetition operator allows zero repetitions of it, then the function
+sets @code{@w{@var{regs}->}start[@var{i}]} and
+@code{@w{@var{regs}->}end[@var{i}]} to @math{-1}.
+
+For example, when you match the pattern @samp{(a)*b} against
+the string @samp{b}, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]}
+
+@item
+@math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]}
+@end itemize
+
+@item
+If the @w{@var{i}-th} group matches a zero-length string, then the
+function sets @code{@w{@var{regs}->}start[@var{i}]} and
+@code{@w{@var{regs}->}end[@var{i}]} to the index just beyond that
+zero-length string.
+
+For example, when you match the pattern @samp{(a*)b} against the string
+@samp{b}, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]}
+
+@item
+0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]}
+@end itemize
+
+@ignore
+The function sets @code{@w{@var{regs}->}start[0]} and
+@code{@w{@var{regs}->}end[0]} to analogous information about the entire
+pattern.
+
+For example, when you match the pattern @samp{(a*)} against the empty
+string, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 0 in @code{@w{@var{regs}->}end[0]}
+
+@item
+0 in @code{@w{@var{regs}->}start[1]} and 0 in @code{@w{@var{regs}->}end[1]}
+@end itemize
+@end ignore
+
+@item
+If an @w{@var{i}-th} group contains a @w{@var{j}-th} group
+in turn not contained within any other group within group @var{i} and
+the function reports a match of the @w{@var{i}-th} group, then it
+records in @code{@w{@var{regs}->}start[@var{j}]} and
+@code{@w{@var{regs}->}end[@var{j}]} the last match (if it matched) of
+the @w{@var{j}-th} group.
+
+For example, when you match the pattern @samp{((a*)b)*} against the
+string @samp{abb}, @w{group 2} last matches the empty string, so you
+get what it previously matched:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]}
+
+@item
+2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]}
+
+@item
+2 in @code{@w{@var{regs}->}start[2]} and 2 in @code{@w{@var{regs}->}end[2]}
+@end itemize
+
+When you match the pattern @samp{((a)*b)*} against the string
+@samp{abb}, @w{group 2} doesn't participate in the last match, so you
+get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 3 in @code{@w{@var{regs}->}end[0]}
+
+@item
+2 in @code{@w{@var{regs}->}start[1]} and 3 in @code{@w{@var{regs}->}end[1]}
+
+@item
+0 in @code{@w{@var{regs}->}start[2]} and 1 in @code{@w{@var{regs}->}end[2]}
+@end itemize
+
+@item
+If an @w{@var{i}-th} group contains a @w{@var{j}-th} group
+in turn not contained within any other group within group @var{i}
+and the function sets
+@code{@w{@var{regs}->}start[@var{i}]} and
+@code{@w{@var{regs}->}end[@var{i}]} to @math{-1}, then it also sets
+@code{@w{@var{regs}->}start[@var{j}]} and
+@code{@w{@var{regs}->}end[@var{j}]} to @math{-1}.
+
+For example, when you match the pattern @samp{((a)*b)*c} against the
+string @samp{c}, you get:
+
+@itemize
+@item
+0 in @code{@w{@var{regs}->}start[0]} and 1 in @code{@w{@var{regs}->}end[0]}
+
+@item
+@math{-1} in @code{@w{@var{regs}->}start[1]} and @math{-1} in @code{@w{@var{regs}->}end[1]}
+
+@item
+@math{-1} in @code{@w{@var{regs}->}start[2]} and @math{-1} in @code{@w{@var{regs}->}end[2]}
+@end itemize
+
+@end itemize
+
+@node Freeing GNU Pattern Buffers, , Using Registers, GNU Regex Functions
+@subsection Freeing GNU Pattern Buffers
+
+To free any allocated fields of a pattern buffer, you can use the
+@sc{posix} function described in @ref{Freeing POSIX Pattern Buffers},
+since the type @code{regex_t}---the type for @sc{posix} pattern
+buffers---is equivalent to the type @code{re_pattern_buffer}. After
+freeing a pattern buffer, you need to again compile a regular expression
+in it (@pxref{GNU Regular Expression Compiling}) before passing it to
+a matching or searching function.
+
+
+@node POSIX Regex Functions, BSD Regex Functions, GNU Regex Functions, Programming with Regex
+@section POSIX Regex Functions
+
+If you're writing code that has to be @sc{posix} compatible, you'll need
+to use these functions. Their interfaces are as specified by @sc{posix},
+draft 1003.2/D11.2.
+
+@menu
+* POSIX Pattern Buffers:: The regex_t type.
+* POSIX Regular Expression Compiling:: regcomp ()
+* POSIX Matching:: regexec ()
+* Reporting Errors:: regerror ()
+* Using Byte Offsets:: The regmatch_t type.
+* Freeing POSIX Pattern Buffers:: regfree ()
+@end menu
+
+
+@node POSIX Pattern Buffers, POSIX Regular Expression Compiling, , POSIX Regex Functions
+@subsection POSIX Pattern Buffers
+
+To compile or match a given regular expression the @sc{posix} way, you
+must supply a pattern buffer exactly the way you do for @sc{gnu}
+(@pxref{GNU Pattern Buffers}). @sc{posix} pattern buffers have type
+@code{regex_t}, which is equivalent to the @sc{gnu} pattern buffer
+type @code{re_pattern_buffer}.
+
+
+@node POSIX Regular Expression Compiling, POSIX Matching, POSIX Pattern Buffers, POSIX Regex Functions
+@subsection POSIX Regular Expression Compiling
+
+With @sc{posix}, you can only search for a given regular expression; you
+can't match it. To do this, you must first compile it in a
+pattern buffer, using @code{regcomp}.
+
+@ignore
+Before calling @code{regcomp}, you must initialize this pattern buffer
+as you do for @sc{gnu} (@pxref{GNU Regular Expression Compiling}). See
+below, however, for how to choose a syntax with which to compile.
+@end ignore
+
+To compile a pattern buffer, use:
+
+@findex regcomp
+@example
+int
+regcomp (regex_t *@var{preg}, const char *@var{regex}, int @var{cflags})
+@end example
+
+@noindent
+@var{preg} is the initialized pattern buffer's address, @var{regex} is
+the regular expression's address, and @var{cflags} is the compilation
+flags, which Regex considers as a collection of bits. Here are the
+valid bits, as defined in @file{regex.h}:
+
+@table @code
+
+@item REG_EXTENDED
+@vindex REG_EXTENDED
+says to use @sc{posix} Extended Regular Expression syntax; if this isn't
+set, then says to use @sc{posix} Basic Regular Expression syntax.
+@code{regcomp} sets @var{preg}'s @code{syntax} field accordingly.
+
+@item REG_ICASE
+@vindex REG_ICASE
+@cindex ignoring case
+says to ignore case; @code{regcomp} sets @var{preg}'s @code{translate}
+field to a translate table which ignores case, replacing anything you've
+put there before.
+
+@item REG_NOSUB
+@vindex REG_NOSUB
+says to set @var{preg}'s @code{no_sub} field; @pxref{POSIX Matching},
+for what this means.
+
+@item REG_NEWLINE
+@vindex REG_NEWLINE
+says that a:
+
+@itemize @bullet
+
+@item
+match-any-character operator (@pxref{Match-any-character
+Operator}) doesn't match a newline.
+
+@item
+nonmatching list not containing a newline (@pxref{List
+Operators}) matches a newline.
+
+@item
+match-beginning-of-line operator (@pxref{Match-beginning-of-line
+Operator}) matches the empty string immediately after a newline,
+regardless of how @code{REG_NOTBOL} is set (@pxref{POSIX Matching}, for
+an explanation of @code{REG_NOTBOL}).
+
+@item
+match-end-of-line operator (@pxref{Match-beginning-of-line
+Operator}) matches the empty string immediately before a newline,
+regardless of how @code{REG_NOTEOL} is set (@pxref{POSIX Matching},
+for an explanation of @code{REG_NOTEOL}).
+
+@end itemize
+
+@end table
+
+If @code{regcomp} successfully compiles the regular expression, it
+returns zero and sets @code{*@var{pattern_buffer}} to the compiled
+pattern. Except for @code{syntax} (which it sets as explained above), it
+also sets the same fields the same way as does the @sc{gnu} compiling
+function (@pxref{GNU Regular Expression Compiling}).
+
+If @code{regcomp} can't compile the regular expression, it returns one
+of the error codes listed here. (Except when noted differently, the
+syntax of in all examples below is basic regular expression syntax.)
+
+@table @code
+
+@comment repetitions
+@item REG_BADRPT
+For example, the consecutive repetition operators @samp{**} in
+@samp{a**} are invalid. As another example, if the syntax is extended
+regular expression syntax, then the repetition operator @samp{*} with
+nothing on which to operate in @samp{*} is invalid.
+
+@item REG_BADBR
+For example, the @var{count} @samp{-1} in @samp{a\@{-1} is invalid.
+
+@item REG_EBRACE
+For example, @samp{a\@{1} is missing a close-interval operator.
+
+@comment lists
+@item REG_EBRACK
+For example, @samp{[a} is missing a close-list operator.
+
+@item REG_ERANGE
+For example, the range ending point @samp{z} that collates lower than
+does its starting point @samp{a} in @samp{[z-a]} is invalid. Also, the
+range with the character class @samp{[:alpha:]} as its starting point in
+@samp{[[:alpha:]-|]}.
+
+@item REG_ECTYPE
+For example, the character class name @samp{foo} in @samp{[[:foo:]} is
+invalid.
+
+@comment groups
+@item REG_EPAREN
+For example, @samp{a\)} is missing an open-group operator and @samp{\(a}
+is missing a close-group operator.
+
+@item REG_ESUBREG
+For example, the back reference @samp{\2} that refers to a nonexistent
+subexpression in @samp{\(a\)\2} is invalid.
+
+@comment unfinished business
+
+@item REG_EEND
+Returned when a regular expression causes no other more specific error.
+
+@item REG_EESCAPE
+For example, the trailing backslash @samp{\} in @samp{a\} is invalid, as is the
+one in @samp{\}.
+
+@comment kitchen sink
+@item REG_BADPAT
+For example, in the extended regular expression syntax, the empty group
+@samp{()} in @samp{a()b} is invalid.
+
+@comment internal
+@item REG_ESIZE
+Returned when a regular expression needs a pattern buffer larger than
+65536 bytes.
+
+@item REG_ESPACE
+Returned when a regular expression makes Regex to run out of memory.
+
+@end table
+
+
+@node POSIX Matching, Reporting Errors, POSIX Regular Expression Compiling, POSIX Regex Functions
+@subsection POSIX Matching
+
+Matching the @sc{posix} way means trying to match a null-terminated
+string starting at its first character. Once you've compiled a pattern
+into a pattern buffer (@pxref{POSIX Regular Expression Compiling}), you
+can ask the matcher to match that pattern against a string using:
+
+@findex regexec
+@example
+int
+regexec (const regex_t *@var{preg}, const char *@var{string},
+ size_t @var{nmatch}, regmatch_t @var{pmatch}[], int @var{eflags})
+@end example
+
+@noindent
+@var{preg} is the address of a pattern buffer for a compiled pattern.
+@var{string} is the string you want to match.
+
+@xref{Using Byte Offsets}, for an explanation of @var{pmatch}. If you
+pass zero for @var{nmatch} or you compiled @var{preg} with the
+compilation flag @code{REG_NOSUB} set, then @code{regexec} will ignore
+@var{pmatch}; otherwise, you must allocate it to have at least
+@var{nmatch} elements. @code{regexec} will record @var{nmatch} byte
+offsets in @var{pmatch}, and set to @math{-1} any unused elements up to
+@math{@var{pmatch}@code{[@var{nmatch}]} - 1}.
+
+@var{eflags} specifies @dfn{execution flags}---namely, the two bits
+@code{REG_NOTBOL} and @code{REG_NOTEOL} (defined in @file{regex.h}). If
+you set @code{REG_NOTBOL}, then the match-beginning-of-line operator
+(@pxref{Match-beginning-of-line Operator}) always fails to match.
+This lets you match against pieces of a line, as you would need to if,
+say, searching for repeated instances of a given pattern in a line; it
+would work correctly for patterns both with and without
+match-beginning-of-line operators. @code{REG_NOTEOL} works analogously
+for the match-end-of-line operator (@pxref{Match-end-of-line
+Operator}); it exists for symmetry.
+
+@code{regexec} tries to find a match for @var{preg} in @var{string}
+according to the syntax in @var{preg}'s @code{syntax} field.
+(@xref{POSIX Regular Expression Compiling}, for how to set it.) The
+function returns zero if the compiled pattern matches @var{string} and
+@code{REG_NOMATCH} (defined in @file{regex.h}) if it doesn't.
+
+@node Reporting Errors, Using Byte Offsets, POSIX Matching, POSIX Regex Functions
+@subsection Reporting Errors
+
+If either @code{regcomp} or @code{regexec} fail, they return a nonzero
+error code, the possibilities for which are defined in @file{regex.h}.
+@xref{POSIX Regular Expression Compiling}, and @ref{POSIX Matching}, for
+what these codes mean. To get an error string corresponding to these
+codes, you can use:
+
+@findex regerror
+@example
+size_t
+regerror (int @var{errcode},
+ const regex_t *@var{preg},
+ char *@var{errbuf},
+ size_t @var{errbuf_size})
+@end example
+
+@noindent
+@var{errcode} is an error code, @var{preg} is the address of the pattern
+buffer which provoked the error, @var{errbuf} is the error buffer, and
+@var{errbuf_size} is @var{errbuf}'s size.
+
+@code{regerror} returns the size in bytes of the error string
+corresponding to @var{errcode} (including its terminating null). If
+@var{errbuf} and @var{errbuf_size} are nonzero, it also returns in
+@var{errbuf} the first @math{@var{errbuf_size} - 1} characters of the
+error string, followed by a null.
+@var{errbuf_size} must be a nonnegative number less than or equal to the
+size in bytes of @var{errbuf}.
+
+You can call @code{regerror} with a null @var{errbuf} and a zero
+@var{errbuf_size} to determine how large @var{errbuf} need be to
+accommodate @code{regerror}'s error string.
+
+@node Using Byte Offsets, Freeing POSIX Pattern Buffers, Reporting Errors, POSIX Regex Functions
+@subsection Using Byte Offsets
+
+In @sc{posix}, variables of type @code{regmatch_t} hold analogous
+information, but are not identical to, @sc{gnu}'s registers (@pxref{Using
+Registers}). To get information about registers in @sc{posix}, pass to
+@code{regexec} a nonzero @var{pmatch} of type @code{regmatch_t}, i.e.,
+the address of a structure of this type, defined in
+@file{regex.h}:
+
+@tindex regmatch_t
+@example
+typedef struct
+@{
+ regoff_t rm_so;
+ regoff_t rm_eo;
+@} regmatch_t;
+@end example
+
+When reading in @ref{Using Registers}, about how the matching function
+stores the information into the registers, substitute @var{pmatch} for
+@var{regs}, @code{@w{@var{pmatch}[@var{i}]->}rm_so} for
+@code{@w{@var{regs}->}start[@var{i}]} and
+@code{@w{@var{pmatch}[@var{i}]->}rm_eo} for
+@code{@w{@var{regs}->}end[@var{i}]}.
+
+@node Freeing POSIX Pattern Buffers, , Using Byte Offsets, POSIX Regex Functions
+@subsection Freeing POSIX Pattern Buffers
+
+To free any allocated fields of a pattern buffer, use:
+
+@findex regfree
+@example
+void
+regfree (regex_t *@var{preg})
+@end example
+
+@noindent
+@var{preg} is the pattern buffer whose allocated fields you want freed.
+@code{regfree} also sets @var{preg}'s @code{allocated} and @code{used}
+fields to zero. After freeing a pattern buffer, you need to again
+compile a regular expression in it (@pxref{POSIX Regular Expression
+Compiling}) before passing it to the matching function (@pxref{POSIX
+Matching}).
+
+
+@node BSD Regex Functions, , POSIX Regex Functions, Programming with Regex
+@section BSD Regex Functions
+
+If you're writing code that has to be Berkeley @sc{unix} compatible,
+you'll need to use these functions whose interfaces are the same as those
+in Berkeley @sc{unix}.
+
+@menu
+* BSD Regular Expression Compiling:: re_comp ()
+* BSD Searching:: re_exec ()
+@end menu
+
+@node BSD Regular Expression Compiling, BSD Searching, , BSD Regex Functions
+@subsection BSD Regular Expression Compiling
+
+With Berkeley @sc{unix}, you can only search for a given regular
+expression; you can't match one. To search for it, you must first
+compile it. Before you compile it, you must indicate the regular
+expression syntax you want it compiled according to by setting the
+variable @code{re_syntax_options} (declared in @file{regex.h} to some
+syntax (@pxref{Regular Expression Syntax}).
+
+To compile a regular expression use:
+
+@findex re_comp
+@example
+char *
+re_comp (char *@var{regex})
+@end example
+
+@noindent
+@var{regex} is the address of a null-terminated regular expression.
+@code{re_comp} uses an internal pattern buffer, so you can use only the
+most recently compiled pattern buffer. This means that if you want to
+use a given regular expression that you've already compiled---but it
+isn't the latest one you've compiled---you'll have to recompile it. If
+you call @code{re_comp} with the null string (@emph{not} the empty
+string) as the argument, it doesn't change the contents of the pattern
+buffer.
+
+If @code{re_comp} successfully compiles the regular expression, it
+returns zero. If it can't compile the regular expression, it returns
+an error string. @code{re_comp}'s error messages are identical to those
+of @code{re_compile_pattern} (@pxref{GNU Regular Expression
+Compiling}).
+
+@node BSD Searching, , BSD Regular Expression Compiling, BSD Regex Functions
+@subsection BSD Searching
+
+Searching the Berkeley @sc{unix} way means searching in a string
+starting at its first character and trying successive positions within
+it to find a match. Once you've compiled a pattern using @code{re_comp}
+(@pxref{BSD Regular Expression Compiling}), you can ask Regex
+to search for that pattern in a string using:
+
+@findex re_exec
+@example
+int
+re_exec (char *@var{string})
+@end example
+
+@noindent
+@var{string} is the address of the null-terminated string in which you
+want to search.
+
+@code{re_exec} returns either 1 for success or 0 for failure. It
+automatically uses a @sc{gnu} fastmap (@pxref{Searching with Fastmaps}).
+
+
+@node Copying, Index, Programming with Regex, Top
+@appendix GNU GENERAL PUBLIC LICENSE
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
+675 Mass Ave, Cambridge, MA 02139, USA
+
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+@end display
+
+@unnumberedsec 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.
+
+@iftex
+@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+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.
+
+@item
+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.
+
+@item
+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:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+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.
+
+@item
+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.)
+@end enumerate
+
+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.
+
+@item
+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:
+
+@enumerate a
+@item
+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,
+
+@item
+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,
+
+@item
+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.)
+@end enumerate
+
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+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.
+
+@item
+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 enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@unnumberedsec 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.
+
+@smallexample
+@var{one line to give the program's name and a brief idea of what it does.}
+Copyright (C) 19@var{yy} @var{name of author}
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.
+@end smallexample
+
+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:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{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.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{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:
+
+@example
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+`Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end example
+
+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.
+
+
+@node Index, , Copying, Top
+@unnumbered Index
+
+@printindex cp
+
+@contents
+
+@bye
diff --git a/gnu/lib/libregex/regex.c b/gnu/lib/libregex/regex.c
new file mode 100644
index 0000000..956d2f5
--- /dev/null
+++ b/gnu/lib/libregex/regex.c
@@ -0,0 +1,5086 @@
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P10003.2/D11.2, except for
+ internationalization features.)
+
+ Copyright (C) 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (REGEX_MALLOC)
+ #pragma alloca
+#endif
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(STDC_HEADERS) && !defined(emacs)
+#include <stddef.h>
+#else
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+#include <sys/types.h>
+#endif
+
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
+
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+/* Emacs uses `NULL' as a predicate. */
+#undef NULL
+
+#else /* not emacs */
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ `BSTRING', as far as I know, and neither of them use this code. */
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+#else
+#include <strings.h>
+#endif
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE 256
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+
+#endif /* not SYNTAX_TABLE */
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+#ifdef __FreeBSD__
+#include <locale.h>
+#endif
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding." */
+#if ! defined (isascii) || defined (STDC_HEADERS)
+#undef isascii
+#define isascii(c) 1
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (isascii (c) && isblank (c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (isascii (c) && isgraph (c))
+#else
+#define ISGRAPH(c) (isascii (c) && isprint (c) && !isspace (c))
+#endif
+
+#define ISPRINT(c) (isascii (c) && isprint (c))
+#define ISDIGIT(c) (isascii (c) && isdigit (c))
+#define ISALNUM(c) (isascii (c) && isalnum (c))
+#define ISALPHA(c) (isascii (c) && isalpha (c))
+#define ISCNTRL(c) (isascii (c) && iscntrl (c))
+#define ISLOWER(c) (isascii (c) && islower (c))
+#define ISPUNCT(c) (isascii (c) && ispunct (c))
+#define ISSPACE(c) (isascii (c) && isspace (c))
+#define ISUPPER(c) (isascii (c) && isupper (c))
+#define ISXDIGIT(c) (isascii (c) && isxdigit (c))
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
+
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE malloc
+#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+#ifndef alloca
+
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top. */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+#define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+#define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ bcopy (source, destination, osize), \
+ destination)
+
+#endif /* not REGEX_MALLOC */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression.
+
+ The value of `exactn' is needed in search.c (search_buffer) in Emacs.
+ So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+ `exactn' we use here must also be 1. */
+
+typedef enum
+{
+ no_op = 0,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn = 1,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number _RE_ARGS((int *dest, unsigned char *source));
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+#ifndef EXTRACT_MACROS /* To debug the macros. */
+#undef EXTRACT_NUMBER
+#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number_and_incr _RE_ARGS((int *destination,
+ unsigned char **source));
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+#ifndef EXTRACT_MACROS
+#undef EXTRACT_NUMBER_AND_INCR
+#define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+#include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+#include <assert.h>
+
+static int debug = 0;
+
+#define DEBUG_STATEMENT(e) e
+#define DEBUG_PRINT1(x) if (debug) printf (x)
+#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+extern void printchar ();
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ printchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ printchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ printf ("%d:\t", p - start);
+
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ printchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ printchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ printchar (c);
+
+ last = c;
+ }
+
+ if (in_range)
+ printchar (last);
+
+ putchar (']');
+
+ p += 1 + *p;
+ }
+ break;
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+#ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+#endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+
+ putchar ('\n');
+ }
+
+ printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %d\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ unsigned this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ printchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ printchar (string2[this_char]);
+ }
+}
+
+#else /* not DEBUG */
+
+#undef assert
+#define assert(e)
+
+#define DEBUG_STATEMENT(e)
+#define DEBUG_PRINT1(x)
+#define DEBUG_PRINT2(x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+ return ret;
+}
+
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there. */
+
+static const char *re_error_msg[] =
+ { NULL, /* REG_NOERROR */
+ "No match", /* REG_NOMATCH */
+ "Invalid regular expression", /* REG_BADPAT */
+ "Invalid collation character", /* REG_ECOLLATE */
+ "Invalid character class name", /* REG_ECTYPE */
+ "Trailing backslash", /* REG_EESCAPE */
+ "Invalid back reference", /* REG_ESUBREG */
+ "Unmatched [ or [^", /* REG_EBRACK */
+ "Unmatched ( or \\(", /* REG_EPAREN */
+ "Unmatched \\{", /* REG_EBRACE */
+ "Invalid content of \\{\\}", /* REG_BADBR */
+ "Invalid range end", /* REG_ERANGE */
+ "Memory exhausted", /* REG_ESPACE */
+ "Invalid preceding regular expression", /* REG_BADRPT */
+ "Premature end of regular expression", /* REG_EEND */
+ "Regular expression too big", /* REG_ESIZE */
+ "Unmatched ) or \\)", /* REG_ERPAREN */
+ };
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static reg_errcode_t regex_compile _RE_ARGS((const char *pattern, size_t size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer *bufp));
+static void store_op1 _RE_ARGS((re_opcode_t op, unsigned char *loc, int arg));
+static void store_op2 _RE_ARGS((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2));
+static void insert_op1 _RE_ARGS((re_opcode_t op, unsigned char *loc,
+ int arg, unsigned char *end));
+static void insert_op2 _RE_ARGS((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2, unsigned char *end));
+static boolean at_begline_loc_p _RE_ARGS((const char *pattern, const char *p,
+ reg_syntax_t syntax));
+static boolean at_endline_loc_p _RE_ARGS((const char *p, const char *pend,
+ reg_syntax_t syntax));
+static reg_errcode_t compile_range _RE_ARGS((const char **p_ptr,
+ const char *pend,
+ char *translate,
+ reg_syntax_t syntax,
+ unsigned char *b));
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = translate[c]; \
+ } while (0)
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while (b - bufp->buffer + (n) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (int)((to) - (loc) - 3))
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (int)((to) - (loc) - 3), arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (int)((to) - (loc) - 3), b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (int)((to) - (loc) - 3), arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
+ be too small, many things would have to change. */
+/* Any other compiler which, like MSC, has allocation limit below 2^16
+ bytes will have to use approach similar to what was done below for
+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
+ reallocating to 0 bytes. Such thing is not going to work too well.
+ You have been warned!! */
+#ifdef _MSC_VER
+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
+ The REALLOC define eliminates a flurry of conversion warnings,
+ but is not required. */
+#define MAX_BUF_SIZE 65500L
+#define REALLOC(p,s) realloc((p), (size_t) (s))
+#else
+#define MAX_BUF_SIZE (1L << 16)
+#define REALLOC realloc
+#endif
+
+/* Extend the buffer by twice its current size via realloc and
+ reset the pointers that pointed into the old block to point to the
+ correct places in the new one. If extending the buffer results in it
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) REALLOC(bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
+ } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack. */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+/* int may be not enough when sizeof(int) == 2 */
+typedef long pattern_offset_t;
+
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+#define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+
+static boolean group_in_compile_stack _RE_ARGS((compile_stack_type
+ compile_stack,
+ regnum_t regnum));
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ size_t size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random tempory spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ char *translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
+
+ for (debug_count = 0; debug_count < size; debug_count++)
+ printchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
+
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
+
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ if (bufp->buffer)
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
+ else
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) return REG_ESPACE;
+
+ bufp->allocated = INIT_BUF_SIZE;
+ }
+
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ return REG_BADRPT;
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
+ break;
+
+
+ case '.':
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) return REG_EBRACK;
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) return REG_EBRACK;
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) return REG_EESCAPE;
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ return REG_ERANGE;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) return ret;
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) return ret;
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) return REG_EBRACK;
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and:`]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str)) return REG_ECTYPE;
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) return REG_EBRACK;
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch))
+ || (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch))
+ || (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
+
+
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '|':
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
+
+ case '\\':
+ if (p == pend) return REG_EESCAPE;
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ return REG_ERPAREN;
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ return REG_ERPAREN;
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_EBRACE;
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_BADBR;
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') return REG_EBRACE;
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ return REG_BADBR;
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ return REG_BADRPT;
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
+
+#ifdef emacs
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+
+ case 'w':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ if (re_syntax_options & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ return REG_ESUBREG;
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, (regnum_t)c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
+
+ default:
+ /* Expects the character in `c'. */
+ normal_char:
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ /* Start building a new exactn. */
+
+ laststart = b;
+
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
+
+
+ /* Through the pattern now. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ if (!COMPILE_STACK_EMPTY)
+ return REG_EPAREN;
+
+ free (compile_stack.stack);
+
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
+
+static void
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ reg_syntax_t syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : NULL;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ char *translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ range_start = ((unsigned char *) p)[-2];
+ range_end = ((unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+#ifdef __FreeBSD__
+ if (collate_range_cmp (range_start, range_end) > 0)
+#else
+ if (range_start > range_end)
+#endif
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+#ifdef __FreeBSD__
+ for (this_char = 0; this_char < 1 << BYTEWIDTH; this_char++)
+ if ( collate_range_cmp (range_start, this_char) <= 0
+ && collate_range_cmp (this_char, range_end) <= 0
+ ) {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+#else
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+#endif
+ return REG_NOERROR;
+}
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_SPACE each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+int re_max_failures = 2000;
+
+typedef const unsigned char *fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
+
+
+/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
+
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push PATTERN_OP on FAIL_STACK.
+
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(pattern_op, fail_stack) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (fail_stack)) \
+ ? 0 \
+ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \
+ 1))
+
+/* This pushes an item onto the failure stack. Must be a four-byte
+ value. Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ITEM(item) \
+ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+
+/* The complement operation. Assumes `fail_stack' is nonempty. */
+#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_ITEM
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
+ declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ /* Can't be int, since there is not a shred of a guarantee that int \
+ is wide enough to hold a value of something to which pointer can \
+ be assigned */ \
+ s_reg_t this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ }
+
+#define PUSH_FAILURE_POINT2(pattern_place, string_place, failure_code) \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ PUSH_FAILURE_POINT_LOOP (); \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
+ PUSH_FAILURE_ITEM (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
+ PUSH_FAILURE_ITEM (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_ITEM (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_ITEM (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* Pulled out of PUSH_FAILURE_POINT() to shorten the definition
+ of that macro. (for VAX C) */
+#define PUSH_FAILURE_POINT_LOOP() \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ PUSH_FAILURE_ITEM (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ PUSH_FAILURE_ITEM (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \
+ }
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
+ s_reg_t this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_ITEM (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ POP_FAILURE_POINT2 (low_reg, high_reg, regstart, regend, reg_info);
+
+/* Pulled out of POP_FAILURE_POINT() to shorten the definition
+ of that macro. (for MSC 5.1) */
+#define POP_FAILURE_POINT2(low_reg, high_reg, regstart, regend, reg_info) \
+ \
+ /* Restore register info. */ \
+ high_reg = (active_reg_t) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
+ \
+ low_reg = (active_reg_t) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
+ \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ } \
+ \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
+
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int j, k;
+ fail_stack_type fail_stack;
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+ /* We don't push any register information onto the failure stack. */
+ unsigned num_regs = 0;
+
+ register char *fastmap = bufp->fastmap;
+ unsigned char *pattern = bufp->buffer;
+ const unsigned char *p = pattern;
+ register unsigned char *pend = pattern + bufp->used;
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
+
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
+
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
+ bufp->can_be_null = 0;
+
+ while (p != pend || !FAIL_STACK_EMPTY ())
+ {
+ if (p == pend)
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail];
+ }
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ return 0;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
+ case exactn:
+ fastmap[p[1]] = 1;
+ break;
+
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ break;
+
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
+
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case anychar:
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = 0;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ return 0;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
+#endif /* not emacs */
+
+
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1] == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ return -2;
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
+
+ default:
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+ return 0;
+} /* re_compile_fastmap */
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = 0;
+ }
+}
+
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, startpos, range;
+ struct re_registers *regs;
+{
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
+
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int startpos;
+ int range;
+ struct re_registers *regs;
+ int stop;
+{
+ int val;
+ register char *fastmap = bufp->fastmap;
+ register char *translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register const char *d;
+ register int lim = 0;
+ int irange = range;
+
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (translate)
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
+ else
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
+ goto advance;
+ }
+ }
+
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
+ return -1;
+
+ val = re_match_2 (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+} /* re_search_2 */
+
+/* Structure for per-register (a.k.a. per-group) information.
+ This must not be longer than one word, because we push this value
+ onto the failure stack. Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+
+/* Declarations and macros for re_match_2. */
+
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+static boolean group_match_null_string_p _RE_ARGS((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean alt_match_null_string_p _RE_ARGS((unsigned char *p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean common_op_match_null_string_p _RE_ARGS((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static int bcmp_translate _RE_ARGS((const char *s1, const char *s2,
+ int len, char *translate));
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ active_reg_t r; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ while (0)
+
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) ? (ptr) - string1 : (ptr) - string2 + size1)
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+#define REG_UNSET_VALUE ((char *) -1)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+
+
+/* Free everything we malloc. */
+#ifdef REGEX_MALLOC
+#define FREE_VAR(var) if (var) free (var); var = NULL
+#define FREE_VARIABLES() \
+ do { \
+ FREE_VAR (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else /* not REGEX_MALLOC */
+/* Some MIPS systems (at least) want this to free alloca'd storage. */
+#define FREE_VARIABLES() alloca (0)
+#endif /* not REGEX_MALLOC */
+
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
+
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
+
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+ {
+ return re_match_2 (bufp, NULL, 0, string, size, pos, regs, size);
+}
+#endif /* not emacs */
+
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* We use this to map every character in the string. */
+ char *translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+ fail_stack_type fail_stack;
+#ifdef DEBUG
+ static unsigned failure_id = 0;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ size_t num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+ const char **regstart = 0, **regend = 0;
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+ const char **old_regstart = 0, **old_regend = 0;
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+ register_info_type *reg_info = 0;
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+ const char **best_regstart = 0, **best_regend = 0;
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* Used when we pop values we don't care about. */
+ const char **reg_dummy = 0;
+ register_info_type *reg_info_dummy = 0;
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+#ifdef REGEX_MALLOC
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* REGEX_MALLOC */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
+ {
+ end_match_1 = string1 + stop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + stop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data.
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
+ else
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
+
+ DEBUG_PRINT1 ("The compiled pattern is: ");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
+ {
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+
+ if (p == pend)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
+ {
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set
+ || (same_str_p && d > match_end)
+ || (!same_str_p && !MATCHING_IN_FIRST_STRING))
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. */
+ else if (best_regs_set)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ } /* d != end_match_2 */
+
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ }
+ }
+ else
+ {
+ /* These braces fend off a "empty body in an else-statement"
+ warning under GCC when assert expands to nothing. */
+ assert (bufp->regs_allocated == REGS_FIXED);
+ }
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING ? d - string1
+ : d - string2 + size1);
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt] = POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt] = POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ FREE_VARIABLES ();
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if (translate[(unsigned char) *d++] != (char) *p++)
+ goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
+ break;
+
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
+ case stop_memory:
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || (re_opcode_t) p[-3] == start_memory)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < *p + *(p + 1); r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if ((s_reg_t) old_regend[r] >= (s_reg_t) regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+ PUSH_FAILURE_POINT2(p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
+ ? regend[regno] : end_match_1);
+ for (;;)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : bcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
+
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
+
+
+ /* endline is the dual of begline. */
+ case endline:
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
+ break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ PUSH_FAILURE_POINT2(p + mcnt, NULL, -2);
+ break;
+
+
+ /* Uses of on_failure_jump:
+
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
+ case on_failure_jump:
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ PUSH_FAILURE_POINT2(p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands. */
+ while (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3; /* Skip over args, too. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+ p1 = p + mcnt;
+
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
+ {
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
+ }
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ active_reg_t dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ unconditional_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+ break;
+
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ PUSH_FAILURE_POINT2(0, 0, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ PUSH_FAILURE_POINT2(0, 0, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ break;
+ goto fail;
+
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ goto fail;
+ break;
+
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+#ifdef emacs19
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
+#else /* not emacs19 */
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
+ goto fail;
+ break;
+#endif /* not emacs19 */
+
+ case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ mcnt = (int) Sword;
+ matchsyntax:
+ PREFETCH ();
+ if (SYNTAX (*d++) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+ case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ if (SYNTAX (*d++) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+#endif /* not emacs */
+
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
+ {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
+
+static int
+bcmp_translate (s1, s2, len, translate)
+ const char *s1, *s2;
+ register int len;
+ char *translate;
+{
+ register const unsigned char *p1 = (const unsigned char *) s1,
+ *p2 = (const unsigned char *) s2;
+ while (len)
+ {
+ if (translate[*p1++] != translate[*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ size_t length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ return re_error_msg[(int) ret];
+}
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them if this is an Emacs or POSIX compilation. */
+
+#if !defined (emacs) && !defined (_POSIX_SOURCE)
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return "Memory exhausted";
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ /* Yes, we're discarding `const' here. */
+ return (char *) re_error_msg[(int) ret];
+}
+
+
+int
+re_exec (s)
+ const char *s;
+{
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+#endif /* not emacs and not _POSIX_SOURCE */
+
+/* POSIX.2 functions. Don't define these for Emacs. */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' and `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ reg_syntax_t syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Don't bother to use a fastmap when searching. This simplifies the
+ REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+ characters after newlines into the fastmap. This way, we just try
+ every character. */
+ preg->fastmap = 0;
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate = (char *) malloc (CHAR_SET_SIZE);
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
+ }
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ return (int) ret;
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch, regoff_t);
+ regs.end = TALLOC (nmatch, regoff_t);
+ if (regs.start == NULL || regs.end == NULL)
+ return (int) REG_NOMATCH;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ free (regs.end);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = re_error_msg[errcode];
+
+ /* POSIX doesn't require that we do anything in this case, but why
+ not be nice. */
+ if (! msg)
+ msg = "Success";
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
+ {
+ if (msg_size > errbuf_size)
+ {
+ strncpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+ }
+ else
+ strcpy (errbuf, msg);
+ }
+
+ return msg_size;
+}
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
+}
+
+#endif /* not emacs */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/regex.h b/gnu/lib/libregex/regex.h
new file mode 100644
index 0000000..462d883
--- /dev/null
+++ b/gnu/lib/libregex/regex.h
@@ -0,0 +1,505 @@
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+
+ Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+#include <stddef.h>
+#endif
+
+
+/* The following two types have to be signed and unsigned integer type
+ wide enough to hold a value of a pointer. For most ANSI compilers
+ ptrdiff_t and size_t should be likely OK. Still size of these two
+ types is 2 for Microsoft C. Ugh... */
+typedef long s_reg_t;
+typedef unsigned long active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned long reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1L)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+ IF not set, then the GNU regex operators are recognized. */
+#define RE_NO_GNU_OPS (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_GNU_AWK | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+/* if sizeof(int) == 2, then ((1 << 15) - 1) overflows */
+#define RE_DUP_MAX (0x7fff)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ char *translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+
+/* search.c (search_buffer) in Emacs needs this one opcode value. It is
+ defined both in `regex.c' and here. */
+#define RE_EXACTN_VALUE 1
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#ifdef __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, size_t length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+ _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+ regmatch_t pmatch[], int eflags));
+extern size_t regerror
+ _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+ size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/ChangeLog b/gnu/lib/libregex/test/ChangeLog
new file mode 100644
index 0000000..f0265bb
--- /dev/null
+++ b/gnu/lib/libregex/test/ChangeLog
@@ -0,0 +1,77 @@
+Thu Mar 25 21:23:43 1993 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * debugmalloc.c: #include <string.h>, and remove declaration of
+ memcpy.
+
+Sun Dec 13 20:59:32 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * tregress.c (test_regress): Add regression test for matching
+ "[a-a]" against "a" with the upcase translation map.
+
+ * iregex.c (print_regs): Don't print a newline after the register
+ contents.
+ (main): Instead, write out newlines here after printing match and
+ search results; this way, we get a newline whether or not the
+ pattern matched.
+
+Fri Dec 11 03:30:50 1992 Jim Blandy (jimb@totoro.cs.oberlin.edu)
+
+ * tregress.c (test_regress): Add new test to catch bug fixed by
+ change to regex.c today.
+
+ * Makefile.in (dregex.o): Depend on `../regex.[ch]', not `regex.[ch]'.
+
+Sun Nov 15 07:51:40 1992 Karl Berry (karl@cs.umb.edu)
+
+ * debugmalloc.c (memcpy): Declare; also, include <assert.h>.
+
+ * psx-interf.c (fill_pmatch): Declare offsets as `regoff_t'
+ instead of `off_t'.
+
+Thu Nov 12 11:29:58 1992 Karl Berry (karl@cs.umb.edu)
+
+ * iregex.c (main): Remove unused variable `c'; initialize
+ the char array in C code; only call print_regs if the match and
+ search succeeded.
+ (strlen): Declare.
+
+ * tregress.c (test_regress): Bug from enami.
+
+Tue Nov 10 10:36:53 1992 Karl Berry (karl@cs.umb.edu)
+
+ * tregress.c (test_regress): Remove Emacs 19 diff bug from rms, as
+ it was never the right thing to test anyway, and the test itself
+ had bugs in it.
+
+Mon Nov 9 10:09:40 1992 Karl Berry (karl@cs.umb.edu)
+
+ * tregress.c (test_regress): Bug from meyering.
+
+Thu Sep 24 10:48:34 1992 Karl Berry (karl@cs.umb.edu)
+
+ * Makefile.in: avoid $< (except in implicit rule).
+
+Sat Sep 19 15:38:29 1992 Karl Berry (karl@hayley)
+
+ * Makefile.in (TAGS): include regex.c and regex.h.
+
+Wed Sep 16 09:29:27 1992 Karl Berry (karl@hayley)
+
+ * xmalloc.c (xmalloc): use char *, not void *, as some compilers
+ bomb out on the latter.
+
+ * Makefile.in (LOADLIBES): use LIBS instead, as that what's
+ Autoconf wants to define.
+
+ * other.c: remove tests for ^/$ around newlines.
+
+Tue Sep 15 11:01:15 1992 Karl Berry (karl@hayley)
+
+ * fileregex.c (main): call re_search_2 instead of re_search.
+
+ * Makefile.in (regex.o): make target dregex.o, so VPATH doesn't
+ find ../regex.o.
+
+Sun Sep 13 06:50:03 1992 Karl Berry (karl@hayley)
+
+ * Created.
diff --git a/gnu/lib/libregex/test/Makefile b/gnu/lib/libregex/test/Makefile
new file mode 100644
index 0000000..e8516a8
--- /dev/null
+++ b/gnu/lib/libregex/test/Makefile
@@ -0,0 +1,171 @@
+# $Id: $
+
+# Generated automatically from Makefile.in by configure.
+# Makefile for regex testing.
+#
+# Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CPPFLAGS =
+CFLAGS = -g
+LDFLAGS =
+
+srcdir = .
+VPATH = .:../.
+
+CC = gcc
+DEFS = -DHAVE_STRING_H=1
+LIBS = $(LOADLIBES)
+
+ETAGS = etags
+SHELL = /bin/sh
+
+debug = -DDEBUG
+ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
+
+.c.o:
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
+
+
+# Define this as `../regex.o' to get the optimized version.
+regex_o = dregex.o
+test_h = test.h
+test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
+ psx-generic.o psx-group.o psx-interf.o psx-interv.o
+common_o = printchar.o upcase.o xmalloc.o $(malloc)
+
+# We have a lot of mallocs we can try when we run afoul of strange bugs.
+malloc =
+#malloc = # the libc malloc
+#malloc = g++malloc.o
+#malloc = debugmalloc.o
+#malloc = emacsmalloc.o
+emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
+
+# default is to do nothing.
+default:
+
+all: regex syntax
+
+regex: $(regex_o) $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# As long as we're doing tests, we enable debugging.
+dregex.o: ../regex.c ../regex.h
+ rm -f $@
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
+ mv -f regex.o $@
+
+# iregex is the interactive regex.
+iregex: $(common_o) $(regex_o) iregex.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# fileregex searches for an r.e. in every line of a given file.
+fileregex_o = fileregex.o printchar.o $(regex_o)
+fileregex: $(fileregex_o)
+ $(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
+
+# cppregex is regex with a preprocessed regex.c. Useful when the
+# problem is inside some macro.
+cppregex: regexcpp.o $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+regexcpp.o: regexcpp.c
+
+regexcpp.c: regex.c regexcpp.sed
+ rm -f regexcpp.c
+ $(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
+ | egrep -v '^#|^ *$$' \
+ | sed -f regexcpp.sed \
+ > regexcpp.c
+ chmod a-w regexcpp.c
+
+# Have to give this malloc special flags.
+emacsmalloc.o: emacsmalloc.c
+ $(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
+ ../$(srcdir)/test/emacsmalloc.c
+
+syntax: syntax.o
+ $(CC) $(CFLAGS) -o $@ syntax.o
+
+syntax.c: syntax.skel bits
+ sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
+
+bits: regex.h
+ sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
+ | grep "#define RE_.*1" \
+ | sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
+
+check: regex
+ ./regex
+
+TAGS: regex.c regex.h *.h *.c
+ $(ETAGS) -t $^
+
+depend:
+ gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
+.PHONY: depend
+
+install:
+.PHONY: install
+
+clean mostlyclean:
+ rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
+
+distclean: clean
+ rm -f bits syntax.c Makefile
+
+extraclean: distclean
+ rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
+
+realclean: distclean
+ rm -f TAGS
+
+Makefile: Makefile.in ../config.status
+ (cd ..; sh config.status)
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+# Assumes $(distdir) is the place to put our files.
+distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
+dist: Makefile TAGS
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+
+# Automatically-generated dependencies below here.
+alloca.o : alloca.c
+bsd-interf.o : bsd-interf.c
+debugmalloc.o : debugmalloc.c
+emacsmalloc.o : emacsmalloc.c getpagesize.h
+fileregex.o : fileregex.c .././regex.h
+g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
+iregex.o : iregex.c .././regex.h
+main.o : main.c test.h .././regex.h
+malloc-test.o : malloc-test.c
+other.o : other.c test.h .././regex.h
+printchar.o : printchar.c
+psx-basic.o : psx-basic.c test.h .././regex.h
+psx-extend.o : psx-extend.c test.h .././regex.h
+psx-generic.o : psx-generic.c test.h .././regex.h
+psx-group.o : psx-group.c test.h .././regex.h
+psx-interf.o : psx-interf.c test.h .././regex.h
+psx-interv.o : psx-interv.c test.h .././regex.h
+syntax.o : syntax.c .././regex.h
+test.o : test.c test.h .././regex.h
+tregress.o : tregress.c test.h .././regex.h
+upcase.o : upcase.c
+xmalloc.o : xmalloc.c
diff --git a/gnu/lib/libregex/test/Makefile.in b/gnu/lib/libregex/test/Makefile.in
new file mode 100644
index 0000000..5fc51be
--- /dev/null
+++ b/gnu/lib/libregex/test/Makefile.in
@@ -0,0 +1,170 @@
+# $Id: $
+
+# Makefile for regex testing.
+#
+# Copyright (C) 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CPPFLAGS =
+CFLAGS = -g
+LDFLAGS =
+
+srcdir = @srcdir@
+VPATH = @srcdir@:../@srcdir@
+
+CC = @CC@
+DEFS = @DEFS@
+LIBS = @LIBS@ $(LOADLIBES)
+
+ETAGS = etags
+SHELL = /bin/sh
+
+debug = -DDEBUG
+ALL_CPPFLAGS = -I. -I$(srcdir) -I../$(srcdir) $(DEFS) $(CPPFLAGS) $(debug)
+
+.c.o:
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c $<
+
+
+# Define this as `../regex.o' to get the optimized version.
+regex_o = dregex.o
+test_h = test.h
+test_o = test.o bsd-interf.o other.o tregress.o psx-basic.o psx-extend.o \
+ psx-generic.o psx-group.o psx-interf.o psx-interv.o
+common_o = printchar.o upcase.o xmalloc.o $(malloc)
+
+# We have a lot of mallocs we can try when we run afoul of strange bugs.
+malloc = @ALLOCA@
+#malloc = # the libc malloc
+#malloc = g++malloc.o
+#malloc = debugmalloc.o
+#malloc = emacsmalloc.o
+emacsmallocflags = -Drcheck -Dbotch=abort -DUSG
+
+# default is to do nothing.
+default:
+
+all: regex syntax
+
+regex: $(regex_o) $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# As long as we're doing tests, we enable debugging.
+dregex.o: ../regex.c ../regex.h
+ rm -f $@
+ $(CC) $(ALL_CPPFLAGS) $(CFLAGS) -c ../$(srcdir)/regex.c
+ mv -f regex.o $@
+
+# iregex is the interactive regex.
+iregex: $(common_o) $(regex_o) iregex.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+# fileregex searches for an r.e. in every line of a given file.
+fileregex_o = fileregex.o printchar.o $(regex_o)
+fileregex: $(fileregex_o)
+ $(CC) -o $@ $(LDFLAGS) $(fileregex_o) $(LIBS)
+
+# cppregex is regex with a preprocessed regex.c. Useful when the
+# problem is inside some macro.
+cppregex: regexcpp.o $(common_o) $(test_o) main.o
+ $(CC) -o $@ $(LDFLAGS) $^ $(LIBS)
+
+regexcpp.o: regexcpp.c
+
+regexcpp.c: regex.c regexcpp.sed
+ rm -f regexcpp.c
+ $(CC) -E $(ALL_CPPFLAGS) ../$(srcdir)/regex.c \
+ | egrep -v '^#|^ *$$' \
+ | sed -f regexcpp.sed \
+ > regexcpp.c
+ chmod a-w regexcpp.c
+
+# Have to give this malloc special flags.
+emacsmalloc.o: emacsmalloc.c
+ $(CC) -c $(CFLAGS) $(ALL_CPPFLAGS) $(emacsmallocflags) \
+ ../$(srcdir)/test/emacsmalloc.c
+
+syntax: syntax.o
+ $(CC) $(CFLAGS) -o $@ syntax.o
+
+syntax.c: syntax.skel bits
+ sed '/\[\[\[replace.*\]\]\]/r bits' syntax.skel > $@
+
+bits: regex.h
+ sed -n 1,/RE_SYNTAX_EMACS/p ../$(srcdir)/regex.h \
+ | grep "#define RE_.*1" \
+ | sed 's/^#define \(RE_[A-Z_]*\) .*/ TEST_BIT (\1);/' > $@
+
+check: regex
+ ./regex
+
+TAGS: regex.c regex.h *.h *.c
+ $(ETAGS) -t $^
+
+depend:
+ gcc -MM $(ALL_CPPFLAGS) *.c > /tmp/depend
+.PHONY: depend
+
+install:
+.PHONY: install
+
+clean mostlyclean:
+ rm -f *.o regex cppregex iregex fileregex regexcpp.c syntax
+
+distclean: clean
+ rm -f bits syntax.c Makefile
+
+extraclean: distclean
+ rm -f *~* *\#* patch* *.orig *.rej *.bak core a.out
+
+realclean: distclean
+ rm -f TAGS
+
+Makefile: Makefile.in ../config.status
+ (cd ..; sh config.status)
+
+# Prevent GNU make 3 from overflowing arg limit on system V.
+.NOEXPORT:
+
+# Assumes $(distdir) is the place to put our files.
+distfiles = ChangeLog TAGS *.in *.c *.h regexcpp.sed syntax.skel
+dist: Makefile TAGS
+ mkdir $(distdir)
+ ln $(distfiles) $(distdir)
+
+# Automatically-generated dependencies below here.
+alloca.o : alloca.c
+bsd-interf.o : bsd-interf.c
+debugmalloc.o : debugmalloc.c
+emacsmalloc.o : emacsmalloc.c getpagesize.h
+fileregex.o : fileregex.c .././regex.h
+g++malloc.o : g++malloc.c //usr/include/stdio.h getpagesize.h
+iregex.o : iregex.c .././regex.h
+main.o : main.c test.h .././regex.h
+malloc-test.o : malloc-test.c
+other.o : other.c test.h .././regex.h
+printchar.o : printchar.c
+psx-basic.o : psx-basic.c test.h .././regex.h
+psx-extend.o : psx-extend.c test.h .././regex.h
+psx-generic.o : psx-generic.c test.h .././regex.h
+psx-group.o : psx-group.c test.h .././regex.h
+psx-interf.o : psx-interf.c test.h .././regex.h
+psx-interv.o : psx-interv.c test.h .././regex.h
+syntax.o : syntax.c .././regex.h
+test.o : test.c test.h .././regex.h
+tregress.o : tregress.c test.h .././regex.h
+upcase.o : upcase.c
+xmalloc.o : xmalloc.c
diff --git a/gnu/lib/libregex/test/alloca.c b/gnu/lib/libregex/test/alloca.c
new file mode 100644
index 0000000..d8b6748
--- /dev/null
+++ b/gnu/lib/libregex/test/alloca.c
@@ -0,0 +1,194 @@
+/*
+ alloca -- (mostly) portable public-domain implementation -- D A Gwyn
+
+ last edit: 86/05/30 rms
+ include config.h, since on VMS it renames some symbols.
+ Use xmalloc instead of malloc.
+
+ This implementation of the PWB library alloca() function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+
+ It should work under any C implementation that uses an
+ actual procedure stack (as opposed to a linked list of
+ frames). There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca()-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection.
+*/
+#ifndef lint
+static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
+#endif
+
+#ifdef emacs
+#include "config.h"
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+#ifndef alloca /* If compiling with GCC, this file's not needed. */
+
+#ifdef __STDC__
+typedef void *pointer; /* generic pointer type */
+#else
+typedef char *pointer; /* generic pointer type */
+#endif
+
+#define NULL 0 /* null pointer constant */
+
+extern void free();
+extern pointer xmalloc();
+
+/*
+ Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+*/
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* direction unknown */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* known at compile-time */
+
+#else /* STACK_DIRECTION == 0; need run-time code */
+
+static int stack_dir; /* 1 or -1 once known */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction (/* void */)
+{
+ static char *addr = NULL; /* address of first
+ `dummy', once known */
+ auto char dummy; /* to get stack address */
+
+ if (addr == NULL)
+ { /* initial entry */
+ addr = &dummy;
+
+ find_stack_direction (); /* recurse once */
+ }
+ else /* second entry */
+ if (&dummy > addr)
+ stack_dir = 1; /* stack grew upward */
+ else
+ stack_dir = -1; /* stack grew downward */
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/*
+ An "alloca header" is used to:
+ (a) chain together all alloca()ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc()
+ alignment chunk size. The following default should work okay.
+*/
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* to force sizeof(header) */
+ struct
+ {
+ union hdr *next; /* for chaining headers */
+ char *deep; /* for stack depth measure */
+ } h;
+} header;
+
+/*
+ alloca( size ) returns a pointer to at least `size' bytes of
+ storage which will be automatically reclaimed upon exit from
+ the procedure that called alloca(). Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32.
+*/
+
+static header *last_alloca_header = NULL; /* -> last alloca header */
+
+pointer
+alloca (size) /* returns pointer to storage */
+ unsigned size; /* # bytes to allocate */
+{
+ auto char probe; /* probes stack depth: */
+ register char *depth = &probe;
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* unknown growth direction */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca()ed storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* traverses linked list */
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* collect garbage */
+
+ hp = np; /* -> next header */
+ }
+ else
+ break; /* rest are not deeper */
+
+ last_alloca_header = hp; /* -> last valid storage */
+ }
+
+ if (size == 0)
+ return NULL; /* no allocation required */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = xmalloc (sizeof (header) + size);
+ /* address of header */
+
+ ((header *)new)->h.next = last_alloca_header;
+ ((header *)new)->h.deep = depth;
+
+ last_alloca_header = (header *)new;
+
+ /* User storage begins just after header. */
+
+ return (pointer)((char *)new + sizeof(header));
+ }
+}
+
+#endif /* no alloca */
diff --git a/gnu/lib/libregex/test/bsd-interf.c b/gnu/lib/libregex/test/bsd-interf.c
new file mode 100644
index 0000000..226a513
--- /dev/null
+++ b/gnu/lib/libregex/test/bsd-interf.c
@@ -0,0 +1,38 @@
+/* bsd-interf.c: test BSD interface. */
+
+#ifndef _POSIX_SOURCE /* whole file */
+
+#include "test.h"
+
+void
+test_berk_search (pattern, string)
+ const char *pattern;
+ char *string;
+{
+ const char *return_value = re_comp (pattern);
+
+ if (return_value != 0)
+ {
+ printf ("This didn't compile: `%s'.\n", pattern);
+ printf (" The error message was: `%s'.\n", return_value);
+ }
+ else
+ if (test_should_match && re_exec (string) != strlen (string))
+ {
+ printf ("Should have matched but didn't:\n");
+ printf (" The pattern was: %s.\n", pattern);
+ if (string)
+ printf (" The string was: `%s'.'n", string);
+ else
+ printf (" The string was empty.\n");
+ }
+}
+
+
+void
+test_bsd_interface ()
+{
+ test_berk_search ("a", "ab");
+}
+
+#endif /* _POSIX_SOURCE */
diff --git a/gnu/lib/libregex/test/debugmalloc.c b/gnu/lib/libregex/test/debugmalloc.c
new file mode 100644
index 0000000..6caeb65
--- /dev/null
+++ b/gnu/lib/libregex/test/debugmalloc.c
@@ -0,0 +1,273 @@
+/* debugmalloc.c: a malloc for debugging purposes. */
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+static unsigned trace = 0;
+#define TRACE(s) if (trace) fprintf (stderr, "%s", s)
+#define TRACE1(s, e1) if (trace) fprintf (stderr, s, e1)
+#define TRACE2(s, e1, e2) if (trace) fprintf (stderr, s, e1, e2)
+#define TRACE3(s, e1, e2, e3) if (trace) fprintf (stderr, s, e1, e2, e3)
+#define TRACE4(s, e1, e2, e3, e4) \
+ if (trace) fprintf (stderr, s, e1, e2, e3, e4)
+
+typedef char *address;
+
+
+/* Wrap our calls to sbrk. */
+
+address
+xsbrk (incr)
+ int incr;
+{
+ extern char *sbrk ();
+ address ret = sbrk (incr);
+
+ if (ret == (address) -1)
+ {
+ perror ("sbrk"); /* Actually, we should return NULL, not quit. */
+ abort ();
+ }
+
+ return ret;
+}
+
+
+
+typedef struct chunk_struct
+{
+ /* This is the size (in bytes) that has actually been actually
+ allocated, not the size that the user requested. */
+ unsigned alloc_size;
+
+ /* This is the size the user requested. */
+ unsigned user_size;
+
+ /* Points to the next block in one of the lists. */
+ struct chunk_struct *next;
+
+ /* Now comes the user's memory. */
+ address user_mem;
+
+ /* After the user's memory is a constant. */
+} *chunk;
+
+#define MALLOC_OVERHEAD 16
+
+/* We might play around with the `user_size' field, but the amount of
+ memory that is actually available in the chunk is always the size
+ allocated minus the overhead. */
+#define USER_ALLOC(c) ((c)->alloc_size - MALLOC_OVERHEAD)
+
+/* Given a pointer to a malloc-allocated block, the beginning of the
+ chunk should always be MALLOC_OVERHEAD - 4 bytes back, since the only
+ overhead after the user memory is the constant. */
+
+chunk
+mem_to_chunk (mem)
+ address mem;
+{
+ return (chunk) (mem - (MALLOC_OVERHEAD - 4));
+}
+
+
+/* The other direction is even easier, since the user's memory starts at
+ the `user_mem' member in the chunk. */
+
+address
+chunk_to_mem (c)
+ chunk c;
+{
+ return (address) &(c->user_mem);
+}
+
+
+
+/* We keep both all the allocated chunks and all the free chunks on
+ lists. Since we put the next pointers in the chunk structure, we
+ don't need a separate chunk_list structure. */
+chunk alloc_list = NULL, free_list = NULL;
+
+
+/* We always append the new chunk at the beginning of the list. */
+
+void
+chunk_insert (chunk_list, new_c)
+ chunk *chunk_list;
+ chunk new_c;
+{
+ chunk c = *chunk_list; /* old beginning of list */
+
+ TRACE3 (" Inserting 0x%x at the beginning of 0x%x, before 0x%x.\n",
+ new_c, chunk_list, c);
+
+ *chunk_list = new_c;
+ new_c->next = c;
+}
+
+
+/* Thus, removing an element means we have to search until we find it.
+ Have to delete before we insert, since insertion changes the next
+ pointer, which we need to put it on the other list. */
+
+void
+chunk_delete (chunk_list, dead_c)
+ chunk *chunk_list;
+ chunk dead_c;
+{
+ chunk c = *chunk_list;
+ chunk prev_c = NULL;
+
+ TRACE2 (" Deleting 0x%x from 0x%x:", dead_c, chunk_list);
+
+ while (c != dead_c && c != NULL)
+ {
+ TRACE1 (" 0x%x", c);
+ prev_c = c;
+ c = c->next;
+ }
+
+ if (c == NULL)
+ {
+ fprintf (stderr, "Chunk at 0x%x not found on list.\n", dead_c);
+ abort ();
+ }
+
+ if (prev_c == NULL)
+ {
+ TRACE1 (".\n Setting head to 0x%x.\n", c->next);
+ *chunk_list = c->next;
+ }
+ else
+ {
+ TRACE2 (".\n Linking next(0x%x) to 0x%x.\n", prev_c, c->next);
+ prev_c->next = c->next;
+ }
+}
+
+
+/* See if a list is hunky-dory. */
+
+void
+validate_list (chunk_list)
+ chunk *chunk_list;
+{
+ chunk c;
+
+ TRACE1 (" Validating list at 0x%x:", chunk_list);
+
+ for (c = *chunk_list; c != NULL; c = c->next)
+ {
+ assert (c->user_size < c->alloc_size);
+ assert (memcmp (chunk_to_mem (c) + c->user_size, "Karl", 4));
+ TRACE2 (" 0x%x/%d", c, c->user_size);
+ }
+
+ TRACE (".\n");
+}
+
+
+/* See if we have a free chunk of a given size. We'll take the first
+ one that is big enough. */
+
+chunk
+free_list_available (needed)
+ unsigned needed;
+{
+ chunk c;
+
+ TRACE1 (" Checking free list for %d bytes:", needed);
+
+ if (free_list == NULL)
+ {
+ return NULL;
+ }
+
+ c = free_list;
+
+ while (c != NULL && USER_ALLOC (c) < needed)
+ {
+ TRACE2 (" 0x%x/%d", c, USER_ALLOC (c));
+ c = c->next;
+ }
+
+ TRACE1 ("\n Returning 0x%x.\n", c);
+ return c;
+}
+
+
+
+
+address
+malloc (n)
+ unsigned n;
+{
+ address new_mem;
+ chunk c;
+
+ TRACE1 ("Mallocing %d bytes.\n", n);
+
+ validate_list (&free_list);
+ validate_list (&alloc_list);
+
+ c = free_list_available (n);
+
+ if (c == NULL)
+ { /* Nothing suitable on free list. Allocate a new chunk. */
+ TRACE (" not on free list.\n");
+ c = (chunk) xsbrk (n + MALLOC_OVERHEAD);
+ c->alloc_size = n + MALLOC_OVERHEAD;
+ }
+ else
+ { /* Found something on free list. Don't split it, just use as is. */
+ TRACE (" found on free list.\n");
+ chunk_delete (&free_list, c);
+ }
+
+ /* If we took this from the free list, then the user size might be
+ different now, and consequently the constant at the end might be in
+ the wrong place. */
+ c->user_size = n;
+ new_mem = chunk_to_mem (c);
+ memcpy (new_mem + n, "Karl", 4);
+ chunk_insert (&alloc_list, c);
+
+ TRACE2 ("Malloc returning 0x%x (chunk 0x%x).\n", new_mem, c);
+ return new_mem;
+}
+
+
+address
+realloc (mem, n)
+ address mem;
+ unsigned n;
+{
+ void free ();
+ chunk c = mem_to_chunk (mem);
+ address new_mem;
+
+ TRACE3 ("Reallocing %d bytes at 0x%x (chunk 0x%x).\n", n, mem, c);
+
+ new_mem = malloc (n);
+ memcpy (new_mem, mem, c->user_size);
+ free (mem);
+
+ return new_mem;
+}
+
+
+void
+free (mem)
+ address mem;
+{
+ chunk c = mem_to_chunk (mem);
+
+ TRACE2 ("Freeing memory at 0x%x (chunk at 0x%x).\n", mem, c);
+
+ validate_list (&free_list);
+ validate_list (&alloc_list);
+
+ chunk_delete (&alloc_list, c);
+ chunk_insert (&free_list, c);
+}
diff --git a/gnu/lib/libregex/test/emacsmalloc.c b/gnu/lib/libregex/test/emacsmalloc.c
new file mode 100644
index 0000000..ad7c4da
--- /dev/null
+++ b/gnu/lib/libregex/test/emacsmalloc.c
@@ -0,0 +1,844 @@
+/* dynamic memory allocation for GNU.
+ Copyright (C) 1985, 1987 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, 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! */
+
+
+/*
+ * @(#)nmalloc.c 1 (Caltech) 2/21/82
+ *
+ * U of M Modified: 20 Jun 1983 ACT: strange hacks for Emacs
+ *
+ * Nov 1983, Mike@BRL, Added support for 4.1C/4.2 BSD.
+ *
+ * This is a very fast storage allocator. It allocates blocks of a small
+ * number of different sizes, and keeps free lists of each size. Blocks
+ * that don't exactly fit are passed up to the next larger size. In this
+ * implementation, the available sizes are (2^n)-4 (or -16) bytes long.
+ * This is designed for use in a program that uses vast quantities of
+ * memory, but bombs when it runs out. To make it a little better, it
+ * warns the user when he starts to get near the end.
+ *
+ * June 84, ACT: modified rcheck code to check the range given to malloc,
+ * rather than the range determined by the 2-power used.
+ *
+ * Jan 85, RMS: calls malloc_warning to issue warning on nearly full.
+ * No longer Emacs-specific; can serve as all-purpose malloc for GNU.
+ * You should call malloc_init to reinitialize after loading dumped Emacs.
+ * Call malloc_stats to get info on memory stats if MSTATS turned on.
+ * realloc knows how to return same block given, just changing its size,
+ * if the power of 2 is correct.
+ */
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is 8 bytes. The overhead information will
+ * go in the first int of the block, and the returned pointer will point
+ * to the second.
+ *
+#ifdef MSTATS
+ * nmalloc[i] is the difference between the number of mallocs and frees
+ * for a given block size.
+#endif MSTATS
+ */
+
+#ifdef emacs
+/* config.h specifies which kind of system this is. */
+#include "config.h"
+#include <signal.h>
+#else
+
+/* Determine which kind of system this is. */
+#include <sys/types.h>
+#include <signal.h>
+
+#include <string.h>
+#define bcopy(s,d,n) memcpy ((d), (s), (n))
+#define bcmp(s1,s2,n) memcmp ((s1), (s2), (n))
+#define bzero(s,n) memset ((s), 0, (n))
+
+#ifndef SIGTSTP
+#ifndef VMS
+#ifndef USG
+#define USG
+#endif
+#endif /* not VMS */
+#else /* SIGTSTP */
+#ifdef SIGIO
+#define BSD4_2
+#endif /* SIGIO */
+#endif /* SIGTSTP */
+
+#endif /* not emacs */
+
+/* Define getpagesize () if the system does not. */
+#include "getpagesize.h"
+
+#ifdef BSD
+#ifdef BSD4_1
+#include <sys/vlimit.h> /* warn the user when near the end */
+#else /* if 4.2 or newer */
+#include <sys/time.h>
+#include <sys/resource.h>
+#endif /* if 4.2 or newer */
+#endif
+
+#ifdef VMS
+#include "vlimit.h"
+#endif
+
+extern char *start_of_data ();
+
+#ifdef BSD
+#ifndef DATA_SEG_BITS
+#define start_of_data() &etext
+#endif
+#endif
+
+#ifndef emacs
+#define start_of_data() &etext
+#endif
+
+#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
+#define ISFREE ((char) 0x54) /* magic byte that implies free block */
+ /* this is for error checking only */
+#define ISMEMALIGN ((char) 0xd6) /* Stored before the value returned by
+ memalign, with the rest of the word
+ being the distance to the true
+ beginning of the block. */
+
+extern char etext;
+
+/* These two are for user programs to look at, when they are interested. */
+
+unsigned int malloc_sbrk_used; /* amount of data space used now */
+unsigned int malloc_sbrk_unused; /* amount more we can have */
+
+/* start of data space; can be changed by calling init_malloc */
+static char *data_space_start;
+
+#ifdef MSTATS
+static int nmalloc[30];
+static int nmal, nfre;
+#endif /* MSTATS */
+
+/* If range checking is not turned on, all we have is a flag indicating
+ whether memory is allocated, an index in nextf[], and a size field; to
+ realloc() memory we copy either size bytes or 1<<(index+3) bytes depending
+ on whether the former can hold the exact size (given the value of
+ 'index'). If range checking is on, we always need to know how much space
+ is allocated, so the 'size' field is never used. */
+
+struct mhead {
+ char mh_alloc; /* ISALLOC or ISFREE */
+ char mh_index; /* index in nextf[] */
+/* Remainder are valid only when block is allocated */
+ unsigned short mh_size; /* size, if < 0x10000 */
+#ifdef rcheck
+ unsigned mh_nbytes; /* number of bytes allocated */
+ int mh_magic4; /* should be == MAGIC4 */
+#endif /* rcheck */
+};
+
+/* Access free-list pointer of a block.
+ It is stored at block + 4.
+ This is not a field in the mhead structure
+ because we want sizeof (struct mhead)
+ to describe the overhead for when the block is in use,
+ and we do not want the free-list pointer to count in that. */
+
+#define CHAIN(a) \
+ (*(struct mhead **) (sizeof (char *) + (char *) (a)))
+
+#ifdef rcheck
+
+/* To implement range checking, we write magic values in at the beginning and
+ end of each allocated block, and make sure they are undisturbed whenever a
+ free or a realloc occurs. */
+/* Written in each of the 4 bytes following the block's real space */
+#define MAGIC1 0x55
+/* Written in the 4 bytes before the block's real space */
+#define MAGIC4 0x55555555
+#define ASSERT(p) if (!(p)) botch("p"); else
+#define EXTRA 4 /* 4 bytes extra for MAGIC1s */
+#else
+#define ASSERT(p) if (!(p)) abort (); else
+#define EXTRA 0
+#endif /* rcheck */
+
+
+/* nextf[i] is free list of blocks of size 2**(i + 3) */
+
+static struct mhead *nextf[30];
+
+/* busy[i] is nonzero while allocation of block size i is in progress. */
+
+static char busy[30];
+
+/* Number of bytes of writable memory we can expect to be able to get */
+static unsigned int lim_data;
+
+/* Level number of warnings already issued.
+ 0 -- no warnings issued.
+ 1 -- 75% warning already issued.
+ 2 -- 85% warning already issued.
+*/
+static int warnlevel;
+
+/* Function to call to issue a warning;
+ 0 means don't issue them. */
+static void (*warnfunction) ();
+
+/* nonzero once initial bunch of free blocks made */
+static int gotpool;
+
+char *_malloc_base;
+
+static void getpool ();
+
+/* Cause reinitialization based on job parameters;
+ also declare where the end of pure storage is. */
+void
+malloc_init (start, warnfun)
+ char *start;
+ void (*warnfun) ();
+{
+ if (start)
+ data_space_start = start;
+ lim_data = 0;
+ warnlevel = 0;
+ warnfunction = warnfun;
+}
+
+/* Return the maximum size to which MEM can be realloc'd
+ without actually requiring copying. */
+
+int
+malloc_usable_size (mem)
+ char *mem;
+{
+ struct mhead *p
+ = (struct mhead *) (mem - ((sizeof (struct mhead) + 7) & ~7));
+ int blocksize = 8 << p->mh_index;
+
+ return blocksize - sizeof (struct mhead) - EXTRA;
+}
+
+static void
+morecore (nu) /* ask system for more memory */
+ register int nu; /* size index to get more of */
+{
+ char *sbrk ();
+ register char *cp;
+ register int nblks;
+ register unsigned int siz;
+ int oldmask;
+
+#ifdef BSD
+#ifndef BSD4_1
+ int newmask = -1;
+ /* Blocking these signals interferes with debugging, at least on BSD on
+ the HP 9000/300. */
+#ifdef SIGTRAP
+ newmask &= ~(1 << SIGTRAP);
+#endif
+#ifdef SIGILL
+ newmask &= ~(1 << SIGILL);
+#endif
+#ifdef SIGTSTP
+ newmask &= ~(1 << SIGTSTP);
+#endif
+#ifdef SIGSTOP
+ newmask &= ~(1 << SIGSTOP);
+#endif
+ oldmask = sigsetmask (newmask);
+#endif
+#endif
+
+ if (!data_space_start)
+ {
+ data_space_start = start_of_data ();
+ }
+
+ if (lim_data == 0)
+ get_lim_data ();
+
+ /* On initial startup, get two blocks of each size up to 1k bytes */
+ if (!gotpool)
+ { getpool (); getpool (); gotpool = 1; }
+
+ /* Find current end of memory and issue warning if getting near max */
+
+#ifndef VMS
+ /* Maximum virtual memory on VMS is difficult to calculate since it
+ * depends on several dynmacially changing things. Also, alignment
+ * isn't that important. That is why much of the code here is ifdef'ed
+ * out for VMS systems.
+ */
+ cp = sbrk (0);
+ siz = cp - data_space_start;
+
+ if (warnfunction)
+ switch (warnlevel)
+ {
+ case 0:
+ if (siz > (lim_data / 4) * 3)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 75% of memory limit");
+ }
+ break;
+ case 1:
+ if (siz > (lim_data / 20) * 17)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 85% of memory limit");
+ }
+ break;
+ case 2:
+ if (siz > (lim_data / 20) * 19)
+ {
+ warnlevel++;
+ (*warnfunction) ("Warning: past 95% of memory limit");
+ }
+ break;
+ }
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+#endif /* not VMS */
+
+ /* Take at least 2k, and figure out how many blocks of the desired size
+ we're about to get */
+ nblks = 1;
+ if ((siz = nu) < 8)
+ nblks = 1 << ((siz = 8) - nu);
+
+ if ((cp = sbrk (1 << (siz + 3))) == (char *) -1)
+ {
+#ifdef BSD
+#ifndef BSD4_1
+ sigsetmask (oldmask);
+#endif
+#endif
+ return; /* no more room! */
+ }
+ malloc_sbrk_used = siz;
+ malloc_sbrk_unused = lim_data - siz;
+
+#ifndef VMS
+ if ((int) cp & 7)
+ { /* shouldn't happen, but just in case */
+ cp = (char *) (((int) cp + 8) & ~7);
+ nblks--;
+ }
+#endif /* not VMS */
+
+ /* save new header and link the nblks blocks together */
+ nextf[nu] = (struct mhead *) cp;
+ siz = 1 << (nu + 3);
+ while (1)
+ {
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ if (--nblks <= 0) break;
+ CHAIN ((struct mhead *) cp) = (struct mhead *) (cp + siz);
+ cp += siz;
+ }
+ CHAIN ((struct mhead *) cp) = 0;
+
+#ifdef BSD
+#ifndef BSD4_1
+ sigsetmask (oldmask);
+#endif
+#endif
+}
+
+static void
+getpool ()
+{
+ register int nu;
+ char * sbrk ();
+ register char *cp = sbrk (0);
+
+ if ((int) cp & 0x3ff) /* land on 1K boundaries */
+ sbrk (1024 - ((int) cp & 0x3ff));
+
+ /* Record address of start of space allocated by malloc. */
+ if (_malloc_base == 0)
+ _malloc_base = cp;
+
+ /* Get 2k of storage */
+
+ cp = sbrk (04000);
+ if (cp == (char *) -1)
+ return;
+
+ /* Divide it into an initial 8-word block
+ plus one block of size 2**nu for nu = 3 ... 10. */
+
+ CHAIN (cp) = nextf[0];
+ nextf[0] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = 0;
+ cp += 8;
+
+ for (nu = 0; nu < 7; nu++)
+ {
+ CHAIN (cp) = nextf[nu];
+ nextf[nu] = (struct mhead *) cp;
+ ((struct mhead *) cp) -> mh_alloc = ISFREE;
+ ((struct mhead *) cp) -> mh_index = nu;
+ cp += 8 << nu;
+ }
+}
+
+char *
+malloc (n) /* get a block */
+ unsigned n;
+{
+ register struct mhead *p;
+ register unsigned int nbytes;
+ register int nunits = 0;
+
+ /* Figure out how many bytes are required, rounding up to the nearest
+ multiple of 8, then figure out which nestf[] area to use.
+ Both the beginning of the header and the beginning of the
+ block should be on an eight byte boundary. */
+ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
+ {
+ register unsigned int shiftr = (nbytes - 1) >> 2;
+
+ while (shiftr >>= 1)
+ nunits++;
+ }
+
+ /* In case this is reentrant use of malloc from signal handler,
+ pick a block size that no other malloc level is currently
+ trying to allocate. That's the easiest harmless way not to
+ interfere with the other level of execution. */
+ while (busy[nunits]) nunits++;
+ busy[nunits] = 1;
+
+ /* If there are no blocks of the appropriate size, go get some */
+ /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */
+ if (nextf[nunits] == 0)
+ morecore (nunits);
+
+ /* Get one block off the list, and set the new list head */
+ if ((p = nextf[nunits]) == 0)
+ {
+ busy[nunits] = 0;
+ return 0;
+ }
+ nextf[nunits] = CHAIN (p);
+ busy[nunits] = 0;
+
+ /* Check for free block clobbered */
+ /* If not for this check, we would gobble a clobbered free chain ptr */
+ /* and bomb out on the NEXT allocate of this size block */
+ if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)
+#ifdef rcheck
+ botch ("block on free list clobbered");
+#else /* not rcheck */
+ abort ();
+#endif /* not rcheck */
+
+ /* Fill in the info, and if range checking, set up the magic numbers */
+ p -> mh_alloc = ISALLOC;
+#ifdef rcheck
+ p -> mh_nbytes = n;
+ p -> mh_magic4 = MAGIC4;
+ {
+ /* Get the location n after the beginning of the user's space. */
+ register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n;
+
+ *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;
+ }
+#else /* not rcheck */
+ p -> mh_size = n;
+#endif /* not rcheck */
+#ifdef MSTATS
+ nmalloc[nunits]++;
+ nmal++;
+#endif /* MSTATS */
+ return (char *) p + ((sizeof *p + 7) & ~7);
+}
+
+free (mem)
+ char *mem;
+{
+ register struct mhead *p;
+ {
+ register char *ap = mem;
+
+ if (ap == 0)
+ return;
+
+ p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
+ if (p -> mh_alloc == ISMEMALIGN)
+ {
+ ap -= p->mh_size;
+ p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));
+ }
+
+#ifndef rcheck
+ if (p -> mh_alloc != ISALLOC)
+ abort ();
+
+#else rcheck
+ if (p -> mh_alloc != ISALLOC)
+ {
+ if (p -> mh_alloc == ISFREE)
+ botch ("free: Called with already freed block argument\n");
+ else
+ botch ("free: Called with bad argument\n");
+ }
+
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ ap += p -> mh_nbytes;
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);
+ ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
+#endif /* rcheck */
+ }
+ {
+ register int nunits = p -> mh_index;
+
+ ASSERT (nunits <= 29);
+ p -> mh_alloc = ISFREE;
+
+ /* Protect against signal handlers calling malloc. */
+ busy[nunits] = 1;
+ /* Put this block on the free list. */
+ CHAIN (p) = nextf[nunits];
+ nextf[nunits] = p;
+ busy[nunits] = 0;
+
+#ifdef MSTATS
+ nmalloc[nunits]--;
+ nfre++;
+#endif /* MSTATS */
+ }
+}
+
+char *
+realloc (mem, n)
+ char *mem;
+ register unsigned n;
+{
+ register struct mhead *p;
+ register unsigned int tocopy;
+ register unsigned int nbytes;
+ register int nunits;
+
+ if (mem == 0)
+ return malloc (n);
+ p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7));
+ nunits = p -> mh_index;
+ ASSERT (p -> mh_alloc == ISALLOC);
+#ifdef rcheck
+ ASSERT (p -> mh_magic4 == MAGIC4);
+ {
+ register char *m = mem + (tocopy = p -> mh_nbytes);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);
+ ASSERT (*m++ == MAGIC1); ASSERT (*m == MAGIC1);
+ }
+#else /* not rcheck */
+ if (p -> mh_index >= 13)
+ tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7);
+ else
+ tocopy = p -> mh_size;
+#endif /* not rcheck */
+
+ /* See if desired size rounds to same power of 2 as actual size. */
+ nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;
+
+ /* If ok, use the same block, just marking its size as changed. */
+ if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))
+ {
+#ifdef rcheck
+ register char *m = mem + tocopy;
+ *m++ = 0; *m++ = 0; *m++ = 0; *m++ = 0;
+ p-> mh_nbytes = n;
+ m = mem + n;
+ *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1; *m++ = MAGIC1;
+#else /* not rcheck */
+ p -> mh_size = n;
+#endif /* not rcheck */
+ return mem;
+ }
+
+ if (n < tocopy)
+ tocopy = n;
+ {
+ register char *new;
+
+ if ((new = malloc (n)) == 0)
+ return 0;
+ bcopy (mem, new, tocopy);
+ free (mem);
+ return new;
+ }
+}
+
+/* This is in case something linked with Emacs calls calloc. */
+
+char *
+calloc (num, size)
+ unsigned num, size;
+{
+ register char *mem;
+
+ num *= size;
+ mem = malloc (num);
+ if (mem != 0)
+ bzero (mem, num);
+ return mem;
+}
+
+#ifndef VMS
+
+char *
+memalign (alignment, size)
+ unsigned alignment, size;
+{
+ register char *ptr = malloc (size + alignment);
+ register char *aligned;
+ register struct mhead *p;
+
+ if (ptr == 0)
+ return 0;
+ /* If entire block has the desired alignment, just accept it. */
+ if (((int) ptr & (alignment - 1)) == 0)
+ return ptr;
+ /* Otherwise, get address of byte in the block that has that alignment. */
+ aligned = (char *) (((int) ptr + alignment - 1) & -alignment);
+
+ /* Store a suitable indication of how to free the block,
+ so that free can find the true beginning of it. */
+ p = (struct mhead *) (aligned - ((7 + sizeof (struct mhead)) & ~7));
+ p -> mh_size = aligned - ptr;
+ p -> mh_alloc = ISMEMALIGN;
+ return aligned;
+}
+
+#ifndef HPUX
+/* This runs into trouble with getpagesize on HPUX.
+ Patching out seems cleaner than the ugly fix needed. */
+char *
+valloc (size)
+{
+ return memalign (getpagesize (), size);
+}
+#endif /* not HPUX */
+#endif /* not VMS */
+
+#ifdef MSTATS
+/* Return statistics describing allocation of blocks of size 2**n. */
+
+struct mstats_value
+ {
+ int blocksize;
+ int nfree;
+ int nused;
+ };
+
+struct mstats_value
+malloc_stats (size)
+ int size;
+{
+ struct mstats_value v;
+ register int i;
+ register struct mhead *p;
+
+ v.nfree = 0;
+
+ if (size < 0 || size >= 30)
+ {
+ v.blocksize = 0;
+ v.nused = 0;
+ return v;
+ }
+
+ v.blocksize = 1 << (size + 3);
+ v.nused = nmalloc[size];
+
+ for (p = nextf[size]; p; p = CHAIN (p))
+ v.nfree++;
+
+ return v;
+}
+int
+malloc_mem_used ()
+{
+ int i;
+ int size_used;
+
+ size_used = 0;
+
+ for (i = 0; i < 30; i++)
+ {
+ int allocation_size = 1 << (i + 3);
+ struct mhead *p;
+
+ size_used += nmalloc[i] * allocation_size;
+ }
+
+ return size_used;
+}
+
+int
+malloc_mem_free ()
+{
+ int i;
+ int size_unused;
+
+ size_unused = 0;
+
+ for (i = 0; i < 30; i++)
+ {
+ int allocation_size = 1 << (i + 3);
+ struct mhead *p;
+
+ for (p = nextf[i]; p ; p = CHAIN (p))
+ size_unused += allocation_size;
+ }
+
+ return size_unused;
+}
+#endif /* MSTATS */
+
+/*
+ * This function returns the total number of bytes that the process
+ * will be allowed to allocate via the sbrk(2) system call. On
+ * BSD systems this is the total space allocatable to stack and
+ * data. On USG systems this is the data space only.
+ */
+
+#ifdef USG
+
+get_lim_data ()
+{
+ extern long ulimit ();
+
+#ifdef ULIMIT_BREAK_VALUE
+ lim_data = ULIMIT_BREAK_VALUE;
+#else
+ lim_data = ulimit (3, 0);
+#endif
+
+ lim_data -= (long) data_space_start;
+}
+
+#else /* not USG */
+#if defined (BSD4_1) || defined (VMS)
+
+get_lim_data ()
+{
+ lim_data = vlimit (LIM_DATA, -1);
+}
+
+#else /* not BSD4_1 and not VMS */
+
+get_lim_data ()
+{
+ struct rlimit XXrlimit;
+
+ getrlimit (RLIMIT_DATA, &XXrlimit);
+#ifdef RLIM_INFINITY
+ lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */
+#else
+ lim_data = XXrlimit.rlim_cur; /* soft limit */
+#endif
+}
+
+#endif /* not BSD4_1 and not VMS */
+#endif /* not USG */
+
+#ifdef VMS
+/* There is a problem when dumping and restoring things on VMS. Calls
+ * to SBRK don't necessarily result in contiguous allocation. Dumping
+ * doesn't work when it isn't. Therefore, we make the initial
+ * allocation contiguous by allocating a big chunk, and do SBRKs from
+ * there. Once Emacs has dumped there is no reason to continue
+ * contiguous allocation, malloc doesn't depend on it.
+ *
+ * There is a further problem of using brk and sbrk while using VMS C
+ * run time library routines malloc, calloc, etc. The documentation
+ * says that this is a no-no, although I'm not sure why this would be
+ * a problem. In any case, we remove the necessity to call brk and
+ * sbrk, by calling calloc (to assure zero filled data) rather than
+ * sbrk.
+ *
+ * VMS_ALLOCATION_SIZE is the size of the allocation array. This
+ * should be larger than the malloc size before dumping. Making this
+ * too large will result in the startup procedure slowing down since
+ * it will require more space and time to map it in.
+ *
+ * The value for VMS_ALLOCATION_SIZE in the following define was determined
+ * by running emacs linked (and a large allocation) with the debugger and
+ * looking to see how much storage was used. The allocation was 201 pages,
+ * so I rounded it up to a power of two.
+ */
+#ifndef VMS_ALLOCATION_SIZE
+#define VMS_ALLOCATION_SIZE (512*256)
+#endif
+
+/* Use VMS RTL definitions */
+#undef sbrk
+#undef brk
+#undef malloc
+int vms_out_initial = 0;
+char vms_initial_buffer[VMS_ALLOCATION_SIZE];
+static char *vms_current_brk = &vms_initial_buffer;
+static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1];
+
+#include <stdio.h>
+
+char *
+sys_sbrk (incr)
+ int incr;
+{
+ char *sbrk(), *temp, *ptr;
+
+ if (vms_out_initial)
+ {
+ /* out of initial allocation... */
+ if (!(temp = malloc (incr)))
+ temp = (char *) -1;
+ }
+ else
+ {
+ /* otherwise, go out of our area */
+ ptr = vms_current_brk + incr; /* new current_brk */
+ if (ptr <= vms_end_brk)
+ {
+ temp = vms_current_brk;
+ vms_current_brk = ptr;
+ }
+ else
+ {
+ vms_out_initial = 1; /* mark as out of initial allocation */
+ if (!(temp = malloc (incr)))
+ temp = (char *) -1;
+ }
+ }
+ return temp;
+}
+#endif /* VMS */
diff --git a/gnu/lib/libregex/test/fileregex.c b/gnu/lib/libregex/test/fileregex.c
new file mode 100644
index 0000000..ba81062
--- /dev/null
+++ b/gnu/lib/libregex/test/fileregex.c
@@ -0,0 +1,77 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include "regex.h"
+
+#define BYTEWIDTH 8
+
+/* Sorry, but this is just a test program. */
+#define LINE_MAX 500
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ FILE *f;
+ char *filename;
+ char pat[500]; /* Sorry for that maximum size, too. */
+ char line[LINE_MAX];
+ struct re_pattern_buffer buf;
+ char fastmap[(1 << BYTEWIDTH)];
+ const char *compile_ret;
+ unsigned lineno = 1;
+ unsigned nfound = 0;
+
+ /* Actually, it might be useful to allow the data file to be standard
+ input, and to specify the pattern on the command line. */
+ if (argc != 2)
+ {
+ fprintf (stderr, "Usage: %s <filename>.\n", argv[0]);
+ exit (1);
+ }
+
+ filename = argv[1];
+ f = fopen (filename, "r");
+ if (f == NULL)
+ perror (filename);
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.fastmap = fastmap;
+
+ printf ("Pattern = ", pat);
+ gets (pat);
+
+ if (feof (stdin))
+ {
+ putchar ('\n');
+ exit (0);
+ }
+
+ compile_ret = re_compile_pattern (pat, strlen (pat), &buf);
+ if (compile_ret != NULL)
+ {
+ fprintf (stderr, "%s: %s\n", pat, compile_ret);
+ exit (1);
+ }
+
+ while (fgets (line, LINE_MAX, f) != NULL)
+ {
+ size_t len = strlen (line);
+ struct re_registers regs;
+ int search_ret
+ = re_search_2 (&buf, NULL, 0, line, len, 0, len, &regs, len);
+
+ if (search_ret == -2)
+ {
+ fprintf (stderr, "%s:%d: re_search failed.\n", filename, lineno);
+ exit (1);
+ }
+
+ nfound += search_ret != -1;
+ lineno++;
+ }
+
+ printf ("Matches found: %u (out of %u lines).\n", nfound, lineno - 1);
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/g++malloc.c b/gnu/lib/libregex/test/g++malloc.c
new file mode 100644
index 0000000..88c181c5
--- /dev/null
+++ b/gnu/lib/libregex/test/g++malloc.c
@@ -0,0 +1,1288 @@
+#define inline
+
+/*
+Copyright (C) 1989 Free Software Foundation
+ written by Doug Lea (dl@oswego.edu)
+
+This file is part of GNU CC.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU CC General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU CC, but only under the conditions described in the
+GNU CC General Public License. A copy of this license is
+supposed to have been given to you along with GNU CC so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies.
+*/
+
+
+
+#ifndef NO_LIBGXX_MALLOC /* ignore whole file otherwise */
+
+/* compile with -DMALLOC_STATS to collect statistics */
+/* collecting statistics slows down malloc by at least 15% */
+
+#ifdef MALLOC_STATS
+#define UPDATE_STATS(ARGS) {ARGS;}
+#else
+#define UPDATE_STATS(ARGS)
+#endif
+
+/* History
+
+
+ Tue Jan 16 04:54:27 1990 Doug Lea (dl at g.oswego.edu)
+
+ version 1 released in libg++
+
+ Sun Jan 21 05:52:47 1990 Doug Lea (dl at g.oswego.edu)
+
+ bins are now own struct for, sanity.
+
+ new victim search strategy: scan up and consolidate.
+ Both faster and less fragmentation.
+
+ refined when to scan bins for consolidation, via consollink, etc.
+
+ realloc: always try to expand chunk, avoiding some fragmentation.
+
+ changed a few inlines into macros
+
+ hardwired SBRK_UNIT to 4096 for uniformity across systems
+
+ Tue Mar 20 14:18:23 1990 Doug Lea (dl at g.oswego.edu)
+
+ calloc and cfree now correctly parameterized.
+
+ Sun Apr 1 10:00:48 1990 Doug Lea (dl at g.oswego.edu)
+
+ added memalign and valloc.
+
+ Sun Jun 24 05:46:48 1990 Doug Lea (dl at g.oswego.edu)
+
+ #include gepagesize.h only ifndef sun
+ cache pagesize after first call
+
+ Wed Jul 25 08:35:19 1990 Doug Lea (dl at g.oswego.edu)
+
+ No longer rely on a `designated victim':
+
+ 1. It sometimes caused splits of large chunks
+ when smaller ones would do, leading to
+ bad worst-case fragmentation.
+
+ 2. Scanning through the av array fast anyway,
+ so the overhead isn't worth it.
+
+ To compensate, several other minor changes:
+
+ 1. Unusable chunks are checked for consolidation during
+ searches inside bins, better distributing chunks
+ across bins.
+
+ 2. Chunks are returned when found in malloc_find_space,
+ rather than finishing cleaning everything up, to
+ avoid wasted iterations due to (1).
+*/
+
+/*
+ A version of malloc/free/realloc tuned for C++ applications.
+
+ Here's what you probably want to know first:
+
+ In various tests, this appears to be about as fast as,
+ and usually substantially less memory-wasteful than BSD/GNUemacs malloc.
+
+ Generally, it is slower (by perhaps 20%) than bsd-style malloc
+ only when bsd malloc would waste a great deal of space in
+ fragmented blocks, which this malloc recovers; or when, by
+ chance or design, nearly all requests are near the bsd malloc
+ power-of-2 allocation bin boundaries, and as many chunks are
+ used as are allocated.
+
+ It uses more space than bsd malloc only when, again by chance
+ or design, only bsdmalloc bin-sized requests are malloced, or when
+ little dynamic space is malloced, since this malloc may grab larger
+ chunks from the system at a time than bsd.
+
+ In other words, this malloc seems generally superior to bsd
+ except perhaps for programs that are specially tuned to
+ deal with bsdmalloc's characteristics. But even here, the
+ performance differences are slight.
+
+
+ This malloc, like any other, is a compromised design.
+
+
+ Chunks of memory are maintained using a `boundary tag' method as
+ described in e.g., Knuth or Standish. This means that the size of
+ the chunk is stored both in the front of the chunk and at the end.
+ This makes consolidating fragmented chunks into bigger chunks very fast.
+ The size field is also used to hold bits representing whether a
+ chunk is free or in use.
+
+ Malloced chunks have space overhead of 8 bytes: The preceding
+ and trailing size fields. When they are freed, the list pointer
+ fields are also needed.
+
+ Available chunks are kept in doubly linked lists. The lists are
+ maintained in an array of bins using a power-of-two method, except
+ that instead of 32 bins (one for each 1 << i), there are 128: each
+ power of two is split in quarters. The use of very fine bin sizes
+ closely approximates the use of one bin per actually used size,
+ without necessitating the overhead of locating such bins. It is
+ especially desirable in common C++ applications where large numbers
+ of identically-sized blocks are malloced/freed in some dynamic
+ manner, and then later are all freed. The finer bin sizes make
+ finding blocks fast, with little wasted overallocation. The
+ consolidation methods ensure that once the collection of blocks is
+ no longer useful, fragments are gathered into bigger chunks awaiting new
+ roles.
+
+ The bins av[i] serve as heads of the lists. Bins contain a dummy
+ header for the chunk lists, and a `dirty' field used to indicate
+ whether the list may need to be scanned for consolidation.
+
+ On allocation, the bin corresponding to the request size is
+ scanned, and if there is a chunk with size >= requested, it
+ is split, if too big, and used. Chunks on the list which are
+ too small are examined for consolidation during this traversal.
+
+ If no chunk exists in the list bigger bins are scanned in search of
+ a victim.
+
+ If no victim can be found, then smaller bins are examined for
+ consolidation in order to construct a victim.
+
+ Finally, if consolidation fails to come up with a usable chunk,
+ more space is obtained from the system.
+
+ After a split, the remainder is placed on
+ the back of the appropriate bin list. (All freed chunks are placed
+ on fronts of lists. All remaindered or consolidated chunks are
+ placed on the rear. Correspondingly, searching within a bin
+ starts at the front, but finding victims is from the back. All
+ of this approximates the effect of having 2 kinds of lists per
+ bin: returned chunks vs unallocated chunks, but without the overhead
+ of maintaining 2 lists.)
+
+ Deallocation (free) consists only of placing the chunk on
+ a list.
+
+ Reallocation proceeds in the usual way. If a chunk can be extended,
+ it is, else a malloc-copy-free sequence is taken.
+
+ memalign requests more than enough space from malloc, finds a
+ spot within that chunk that meets the alignment request, and
+ then possibly frees the leading and trailing space. Overreliance
+ on memalign is a sure way to fragment space.
+
+
+ Some other implementation matters:
+
+ 8 byte alignment is currently hardwired into the design. Calling
+ memalign will return a chunk that is both 8-byte aligned, and
+ meets the requested alignment.
+
+ The basic overhead of a used chunk is 8 bytes: 4 at the front and
+ 4 at the end.
+
+ When a chunk is free, 8 additional bytes are needed for free list
+ pointers. Thus, the minimum allocatable size is 16 bytes.
+
+ The existence of front and back overhead permits some reasonably
+ effective fence-bashing checks: The front and back fields must
+ be identical. This is checked only within free() and realloc().
+ The checks are fast enough to be made non-optional.
+
+ The overwriting of parts of freed memory with the freelist pointers
+ can also be very effective (albeit in an annoying way) in helping
+ users track down dangling pointers.
+
+ User overwriting of freed space will often result in crashes
+ within malloc or free.
+
+ These routines are also tuned to C++ in that free(0) is a noop and
+ a failed malloc automatically calls (*new_handler)().
+
+ malloc(0) returns a pointer to something of the minimum allocatable size.
+
+ Additional memory is gathered from the system (via sbrk) in a
+ way that allows chunks obtained across different sbrk calls to
+ be consolidated, but does not require contiguous memory: Thus,
+ it should be safe to intersperse mallocs with other sbrk calls.
+
+ This malloc is NOT designed to work in multiprocessing applications.
+ No semaphores or other concurrency control are provided to ensure
+ that multiple malloc or free calls don't run at the same time,
+ which could be disasterous.
+
+ VERY heavy use of inlines is made, for clarity. If this malloc
+ is ported via a compiler without inlining capabilities, all
+ inlines should be transformed into macros -- making them non-inline
+ makes malloc at least twice as slow.
+
+
+*/
+
+
+/* preliminaries */
+
+#ifdef __cplusplus
+#include <stdio.h>
+#else
+#include "//usr/include/stdio.h" /* needed for error reporting */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USG
+extern void* memset(void*, int, int);
+extern void* memcpy(void*, const void*, int);
+/*inline void bzero(void* s, int l) { memset(s, 0, l); }*/
+#else
+/*extern void bzero(void*, unsigned int);*/
+#endif
+
+/*extern void bcopy(void*, void*, unsigned int);*/
+
+extern void* sbrk(unsigned int);
+
+/* Put this in instead of commmented out stuff above. */
+#define bcopy(s,d,n) memcpy((d),(s),(n))
+#define bcmp(s1,s2,n) memcmp((s1),(s2),(n))
+#define bzero(s,n) memset((s),0,(n))
+
+
+#ifdef __GNUC__
+extern volatile void abort();
+#else
+extern void abort();
+#endif
+
+#ifdef __cplusplus
+}; /* end of extern "C" */
+#endif
+
+
+/* A good multiple to call sbrk with */
+
+#define SBRK_UNIT 4096
+
+
+
+/* how to die on detected error */
+
+#ifdef __GNUC__
+static volatile void malloc_user_error()
+#else
+static void malloc_user_error()
+#endif
+{
+ fputs("malloc/free/realloc: clobbered space detected\n", stderr); abort();
+}
+
+
+
+/* Basic overhead for each malloc'ed chunk */
+
+
+struct malloc_chunk
+{
+ unsigned int size; /* Size in bytes, including overhead. */
+ /* Or'ed with INUSE if in use. */
+
+ struct malloc_chunk* fd; /* double links -- used only if free. */
+ struct malloc_chunk* bk;
+
+};
+
+typedef struct malloc_chunk* mchunkptr;
+
+struct malloc_bin
+{
+ struct malloc_chunk hd; /* dummy list header */
+ unsigned int dirty; /* True if maybe consolidatable */
+ /* Wasting a word here makes */
+ /* sizeof(bin) a power of 2, */
+ /* which makes size2bin() faster */
+};
+
+typedef struct malloc_bin* mbinptr;
+
+
+/* sizes, alignments */
+
+
+#define SIZE_SZ (sizeof(unsigned int))
+#define MALLOC_MIN_OVERHEAD (SIZE_SZ + SIZE_SZ)
+#define MALLOC_ALIGN_MASK (MALLOC_MIN_OVERHEAD - 1)
+
+#define MINSIZE (sizeof(struct malloc_chunk) + SIZE_SZ) /* MUST == 16! */
+
+
+/* pad request bytes into a usable size */
+
+static inline unsigned int request2size(unsigned int request)
+{
+ return (request == 0) ? MINSIZE :
+ ((request + MALLOC_MIN_OVERHEAD + MALLOC_ALIGN_MASK)
+ & ~(MALLOC_ALIGN_MASK));
+}
+
+
+static inline int aligned_OK(void* m)
+{
+ return ((unsigned int)(m) & (MALLOC_ALIGN_MASK)) == 0;
+}
+
+
+/* size field or'd with INUSE when in use */
+#define INUSE 0x1
+
+
+
+/* the bins, initialized to have null double linked lists */
+
+#define MAXBIN 120 /* 1 more than needed for 32 bit addresses */
+
+#define FIRSTBIN (&(av[0]))
+
+static struct malloc_bin av[MAXBIN] =
+{
+ { { 0, &(av[0].hd), &(av[0].hd) }, 0 },
+ { { 0, &(av[1].hd), &(av[1].hd) }, 0 },
+ { { 0, &(av[2].hd), &(av[2].hd) }, 0 },
+ { { 0, &(av[3].hd), &(av[3].hd) }, 0 },
+ { { 0, &(av[4].hd), &(av[4].hd) }, 0 },
+ { { 0, &(av[5].hd), &(av[5].hd) }, 0 },
+ { { 0, &(av[6].hd), &(av[6].hd) }, 0 },
+ { { 0, &(av[7].hd), &(av[7].hd) }, 0 },
+ { { 0, &(av[8].hd), &(av[8].hd) }, 0 },
+ { { 0, &(av[9].hd), &(av[9].hd) }, 0 },
+
+ { { 0, &(av[10].hd), &(av[10].hd) }, 0 },
+ { { 0, &(av[11].hd), &(av[11].hd) }, 0 },
+ { { 0, &(av[12].hd), &(av[12].hd) }, 0 },
+ { { 0, &(av[13].hd), &(av[13].hd) }, 0 },
+ { { 0, &(av[14].hd), &(av[14].hd) }, 0 },
+ { { 0, &(av[15].hd), &(av[15].hd) }, 0 },
+ { { 0, &(av[16].hd), &(av[16].hd) }, 0 },
+ { { 0, &(av[17].hd), &(av[17].hd) }, 0 },
+ { { 0, &(av[18].hd), &(av[18].hd) }, 0 },
+ { { 0, &(av[19].hd), &(av[19].hd) }, 0 },
+
+ { { 0, &(av[20].hd), &(av[20].hd) }, 0 },
+ { { 0, &(av[21].hd), &(av[21].hd) }, 0 },
+ { { 0, &(av[22].hd), &(av[22].hd) }, 0 },
+ { { 0, &(av[23].hd), &(av[23].hd) }, 0 },
+ { { 0, &(av[24].hd), &(av[24].hd) }, 0 },
+ { { 0, &(av[25].hd), &(av[25].hd) }, 0 },
+ { { 0, &(av[26].hd), &(av[26].hd) }, 0 },
+ { { 0, &(av[27].hd), &(av[27].hd) }, 0 },
+ { { 0, &(av[28].hd), &(av[28].hd) }, 0 },
+ { { 0, &(av[29].hd), &(av[29].hd) }, 0 },
+
+ { { 0, &(av[30].hd), &(av[30].hd) }, 0 },
+ { { 0, &(av[31].hd), &(av[31].hd) }, 0 },
+ { { 0, &(av[32].hd), &(av[32].hd) }, 0 },
+ { { 0, &(av[33].hd), &(av[33].hd) }, 0 },
+ { { 0, &(av[34].hd), &(av[34].hd) }, 0 },
+ { { 0, &(av[35].hd), &(av[35].hd) }, 0 },
+ { { 0, &(av[36].hd), &(av[36].hd) }, 0 },
+ { { 0, &(av[37].hd), &(av[37].hd) }, 0 },
+ { { 0, &(av[38].hd), &(av[38].hd) }, 0 },
+ { { 0, &(av[39].hd), &(av[39].hd) }, 0 },
+
+ { { 0, &(av[40].hd), &(av[40].hd) }, 0 },
+ { { 0, &(av[41].hd), &(av[41].hd) }, 0 },
+ { { 0, &(av[42].hd), &(av[42].hd) }, 0 },
+ { { 0, &(av[43].hd), &(av[43].hd) }, 0 },
+ { { 0, &(av[44].hd), &(av[44].hd) }, 0 },
+ { { 0, &(av[45].hd), &(av[45].hd) }, 0 },
+ { { 0, &(av[46].hd), &(av[46].hd) }, 0 },
+ { { 0, &(av[47].hd), &(av[47].hd) }, 0 },
+ { { 0, &(av[48].hd), &(av[48].hd) }, 0 },
+ { { 0, &(av[49].hd), &(av[49].hd) }, 0 },
+
+ { { 0, &(av[50].hd), &(av[50].hd) }, 0 },
+ { { 0, &(av[51].hd), &(av[51].hd) }, 0 },
+ { { 0, &(av[52].hd), &(av[52].hd) }, 0 },
+ { { 0, &(av[53].hd), &(av[53].hd) }, 0 },
+ { { 0, &(av[54].hd), &(av[54].hd) }, 0 },
+ { { 0, &(av[55].hd), &(av[55].hd) }, 0 },
+ { { 0, &(av[56].hd), &(av[56].hd) }, 0 },
+ { { 0, &(av[57].hd), &(av[57].hd) }, 0 },
+ { { 0, &(av[58].hd), &(av[58].hd) }, 0 },
+ { { 0, &(av[59].hd), &(av[59].hd) }, 0 },
+
+ { { 0, &(av[60].hd), &(av[60].hd) }, 0 },
+ { { 0, &(av[61].hd), &(av[61].hd) }, 0 },
+ { { 0, &(av[62].hd), &(av[62].hd) }, 0 },
+ { { 0, &(av[63].hd), &(av[63].hd) }, 0 },
+ { { 0, &(av[64].hd), &(av[64].hd) }, 0 },
+ { { 0, &(av[65].hd), &(av[65].hd) }, 0 },
+ { { 0, &(av[66].hd), &(av[66].hd) }, 0 },
+ { { 0, &(av[67].hd), &(av[67].hd) }, 0 },
+ { { 0, &(av[68].hd), &(av[68].hd) }, 0 },
+ { { 0, &(av[69].hd), &(av[69].hd) }, 0 },
+
+ { { 0, &(av[70].hd), &(av[70].hd) }, 0 },
+ { { 0, &(av[71].hd), &(av[71].hd) }, 0 },
+ { { 0, &(av[72].hd), &(av[72].hd) }, 0 },
+ { { 0, &(av[73].hd), &(av[73].hd) }, 0 },
+ { { 0, &(av[74].hd), &(av[74].hd) }, 0 },
+ { { 0, &(av[75].hd), &(av[75].hd) }, 0 },
+ { { 0, &(av[76].hd), &(av[76].hd) }, 0 },
+ { { 0, &(av[77].hd), &(av[77].hd) }, 0 },
+ { { 0, &(av[78].hd), &(av[78].hd) }, 0 },
+ { { 0, &(av[79].hd), &(av[79].hd) }, 0 },
+
+ { { 0, &(av[80].hd), &(av[80].hd) }, 0 },
+ { { 0, &(av[81].hd), &(av[81].hd) }, 0 },
+ { { 0, &(av[82].hd), &(av[82].hd) }, 0 },
+ { { 0, &(av[83].hd), &(av[83].hd) }, 0 },
+ { { 0, &(av[84].hd), &(av[84].hd) }, 0 },
+ { { 0, &(av[85].hd), &(av[85].hd) }, 0 },
+ { { 0, &(av[86].hd), &(av[86].hd) }, 0 },
+ { { 0, &(av[87].hd), &(av[87].hd) }, 0 },
+ { { 0, &(av[88].hd), &(av[88].hd) }, 0 },
+ { { 0, &(av[89].hd), &(av[89].hd) }, 0 },
+
+ { { 0, &(av[90].hd), &(av[90].hd) }, 0 },
+ { { 0, &(av[91].hd), &(av[91].hd) }, 0 },
+ { { 0, &(av[92].hd), &(av[92].hd) }, 0 },
+ { { 0, &(av[93].hd), &(av[93].hd) }, 0 },
+ { { 0, &(av[94].hd), &(av[94].hd) }, 0 },
+ { { 0, &(av[95].hd), &(av[95].hd) }, 0 },
+ { { 0, &(av[96].hd), &(av[96].hd) }, 0 },
+ { { 0, &(av[97].hd), &(av[97].hd) }, 0 },
+ { { 0, &(av[98].hd), &(av[98].hd) }, 0 },
+ { { 0, &(av[99].hd), &(av[99].hd) }, 0 },
+
+ { { 0, &(av[100].hd), &(av[100].hd) }, 0 },
+ { { 0, &(av[101].hd), &(av[101].hd) }, 0 },
+ { { 0, &(av[102].hd), &(av[102].hd) }, 0 },
+ { { 0, &(av[103].hd), &(av[103].hd) }, 0 },
+ { { 0, &(av[104].hd), &(av[104].hd) }, 0 },
+ { { 0, &(av[105].hd), &(av[105].hd) }, 0 },
+ { { 0, &(av[106].hd), &(av[106].hd) }, 0 },
+ { { 0, &(av[107].hd), &(av[107].hd) }, 0 },
+ { { 0, &(av[108].hd), &(av[108].hd) }, 0 },
+ { { 0, &(av[109].hd), &(av[109].hd) }, 0 },
+
+ { { 0, &(av[110].hd), &(av[110].hd) }, 0 },
+ { { 0, &(av[111].hd), &(av[111].hd) }, 0 },
+ { { 0, &(av[112].hd), &(av[112].hd) }, 0 },
+ { { 0, &(av[113].hd), &(av[113].hd) }, 0 },
+ { { 0, &(av[114].hd), &(av[114].hd) }, 0 },
+ { { 0, &(av[115].hd), &(av[115].hd) }, 0 },
+ { { 0, &(av[116].hd), &(av[116].hd) }, 0 },
+ { { 0, &(av[117].hd), &(av[117].hd) }, 0 },
+ { { 0, &(av[118].hd), &(av[118].hd) }, 0 },
+ { { 0, &(av[119].hd), &(av[119].hd) }, 0 }
+};
+
+/*
+ indexing into bins
+*/
+
+static inline mbinptr size2bin(unsigned int sz)
+{
+ mbinptr b = av;
+ while (sz >= (MINSIZE * 2)) { b += 4; sz >>= 1; } /* find power of 2 */
+ b += (sz - MINSIZE) >> 2; /* find quadrant */
+ return b;
+}
+
+
+
+/* counts maintained if MALLOC_STATS defined */
+
+#ifdef MALLOC_STATS
+
+static unsigned int sbrked_mem;
+static unsigned int requested_mem;
+static unsigned int malloced_mem;
+static unsigned int freed_mem;
+static unsigned int max_used_mem;
+
+static unsigned int n_sbrks;
+static unsigned int n_mallocs;
+static unsigned int n_frees;
+static unsigned int n_reallocs;
+static unsigned int n_reallocs_with_copy;
+static unsigned int n_avail;
+static unsigned int max_inuse;
+
+static unsigned int n_malloc_chunks;
+static unsigned int n_malloc_bins;
+
+static unsigned int n_split;
+static unsigned int n_consol;
+
+
+static void do_malloc_stats(const mchunkptr p)
+{
+ ++n_mallocs;
+ if ((n_mallocs-n_frees) > max_inuse)
+ max_inuse = n_mallocs - n_frees;
+ malloced_mem += (p->size & ~(INUSE));
+ if (malloced_mem - freed_mem > max_used_mem)
+ max_used_mem = malloced_mem - freed_mem;
+}
+
+static void do_free_stats(const mchunkptr p)
+{
+ ++n_frees;
+ freed_mem += (p->size & ~(INUSE));
+}
+
+#endif
+
+
+
+/* Utilities needed below for memalign */
+/* This is redundant with libg++ support, but not if used stand-alone */
+
+static unsigned int gcd(unsigned int a, unsigned int b)
+{
+ unsigned int tmp;
+
+ if (b > a)
+ {
+ tmp = a; a = b; b = tmp;
+ }
+ for(;;)
+ {
+ if (b == 0)
+ return a;
+ else if (b == 1)
+ return b;
+ else
+ {
+ tmp = b;
+ b = a % b;
+ a = tmp;
+ }
+ }
+}
+
+static inline unsigned int lcm(unsigned int x, unsigned int y)
+{
+ return x / gcd(x, y) * y;
+}
+
+
+
+/* maintaining INUSE via size field */
+
+
+#define inuse(p) ((p)->size & INUSE)
+#define set_inuse(p) ((p)->size |= INUSE)
+#define clear_inuse(b) ((p)->size &= ~INUSE)
+
+
+/* operations on malloc_chunk addresses */
+
+
+/* return ptr to next physical malloc_chunk */
+
+#define next_chunk(p) ((mchunkptr)((char*)(p) + (p)->size))
+
+/* return ptr to previous physical malloc_chunk */
+
+#define prev_chunk(p) ((mchunkptr)((char*)(p)-((((int*)(p))[-1]) & ~(INUSE))))
+
+/* place size at front and back of chunk */
+
+
+static inline void set_size(mchunkptr p, unsigned int sz)
+{
+ p->size = *((int*)((char*)(p) + sz - SIZE_SZ)) = sz;
+}
+
+
+
+
+/* conversion from malloc headers to user pointers, and back */
+
+static inline void* chunk2mem(mchunkptr p)
+{
+ void *mem;
+ set_inuse(p);
+mem = (void*)((char*)(p) + SIZE_SZ);
+ return mem;
+}
+
+/* xxxx my own */
+mchunkptr sanity_check(void* mem)
+{
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+
+ /* a quick sanity check */
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ malloc_user_error();
+
+ return p;
+}
+
+
+
+
+static inline mchunkptr mem2chunk(void* mem)
+{
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+
+ /* a quick sanity check */
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ malloc_user_error();
+
+ p->size = sz; /* clears INUSE */
+ return p;
+}
+
+
+
+/* maintaining bins & pointers */
+
+
+/* maximum bin actually used */
+
+static mbinptr malloc_maxbin = FIRSTBIN;
+
+
+/* operations on lists inside bins */
+
+
+/* take a chunk off a list */
+
+static inline void unlink(mchunkptr p)
+{
+ mchunkptr b = p->bk;
+ mchunkptr f = p->fd;
+
+ f->bk = b; b->fd = f;
+
+ UPDATE_STATS (--n_avail);
+}
+
+
+
+/* split a chunk and place on the back of a list */
+
+static inline void split(mchunkptr p, unsigned int offset)
+{
+ unsigned int room = p->size - offset;
+ if (room >= MINSIZE)
+ {
+ mbinptr bn = size2bin(room); /* new bin */
+ mchunkptr h = &(bn->hd); /* its head */
+ mchunkptr b = h->bk; /* old back element */
+ mchunkptr t = (mchunkptr)((char*)(p) + offset); /* remaindered chunk */
+
+ /* set size */
+ t->size = *((int*)((char*)(t) + room - SIZE_SZ)) = room;
+
+ /* link up */
+ t->bk = b; t->fd = h; h->bk = b->fd = t;
+
+ /* adjust maxbin (h == b means was empty) */
+ if (h == b && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ /* adjust size of chunk to be returned */
+ p->size = *((int*)((char*)(p) + offset - SIZE_SZ)) = offset;
+
+ UPDATE_STATS ((++n_split, ++n_avail));
+ }
+}
+
+
+
+/* place a consolidated chunk on the back of a list */
+/* like above, except no split */
+
+static inline void consollink(mchunkptr p)
+{
+ mbinptr bn = size2bin(p->size);
+ mchunkptr h = &(bn->hd);
+ mchunkptr b = h->bk;
+
+ p->bk = b; p->fd = h; h->bk = b->fd = p;
+
+ if (h == b && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ UPDATE_STATS(++n_avail);
+}
+
+
+/* place a freed chunk on the front of a list */
+
+static inline void frontlink(mchunkptr p)
+{
+ mbinptr bn = size2bin(p->size);
+ mchunkptr h = &(bn->hd);
+ mchunkptr f = h->fd;
+
+ p->bk = h; p->fd = f; f->bk = h->fd = p;
+
+ if (h == f && bn > malloc_maxbin) malloc_maxbin = bn;
+
+ bn->dirty = 1;
+
+ UPDATE_STATS(++n_avail);
+}
+
+
+
+/* Dealing with sbrk */
+
+
+/* To link consecutive sbrk regions when possible */
+
+static int* last_sbrk_end;
+
+
+/* who to call when sbrk returns failure */
+
+#ifndef NO_NEW_HANDLER
+typedef volatile void (*vfp)();
+#ifdef __cplusplus
+extern "C" vfp __new_handler;
+#else
+extern vfp __new_handler;
+#endif
+#endif
+
+static mchunkptr malloc_from_sys(unsigned nb)
+{
+ mchunkptr p;
+ unsigned int sbrk_size;
+ int* ip;
+
+ /* Minimally, we need to pad with enough space */
+ /* to place dummy size/use fields to ends if needed */
+
+ sbrk_size = ((nb + SBRK_UNIT - 1 + SIZE_SZ + SIZE_SZ)
+ / SBRK_UNIT) * SBRK_UNIT;
+
+ ip = (int*)(sbrk(sbrk_size));
+ if ((char*)ip == (char*)(-1)) /* sbrk returns -1 on failure */
+ {
+#ifndef NO_NEW_HANDLER
+ (*__new_handler) ();
+#endif
+ return 0;
+ }
+
+ UPDATE_STATS ((++n_sbrks, sbrked_mem += sbrk_size));
+
+
+ if (last_sbrk_end != &ip[-1])
+ {
+ /* It's either first time through or someone else called sbrk. */
+ /* Arrange end-markers at front & back */
+
+ /* Shouldn't be necessary, but better to be safe */
+ while (!aligned_OK(ip)) { ++ip; sbrk_size -= SIZE_SZ; }
+
+
+ /* Mark the front as in use to prevent merging. */
+ /* Note we can get away with only 1 word, not MINSIZE overhead here */
+
+ *ip++ = SIZE_SZ | INUSE;
+
+ p = (mchunkptr)ip;
+ set_size(p,sbrk_size - (SIZE_SZ + SIZE_SZ));
+
+ }
+ else
+ {
+ mchunkptr l;
+
+ /* We can safely make the header start at end of prev sbrked chunk. */
+ /* We will still have space left at the end from a previous call */
+ /* to place the end marker, below */
+
+ p = (mchunkptr)(last_sbrk_end);
+ set_size(p, sbrk_size);
+
+
+ /* Even better, maybe we can merge with last fragment: */
+
+ l = prev_chunk(p);
+ if (!inuse(l))
+ {
+ unlink(l);
+ set_size(l, p->size + l->size);
+ p = l;
+ }
+
+ }
+
+ /* mark the end of sbrked space as in use to prevent merging */
+
+ last_sbrk_end = (int*)((char*)p + p->size);
+ *last_sbrk_end = SIZE_SZ | INUSE;
+
+ UPDATE_STATS((++n_avail, ++n_malloc_chunks));
+
+ /* make it safe to unlink in malloc */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+
+ return p;
+}
+
+
+
+/* Consolidate dirty bins. */
+/* Stop if found a chunk big enough to satisfy current malloc request */
+
+/* (It requires much less bookkeeping to consolidate entire bins */
+/* at once than to keep records of which chunks might be */
+/* consolidatable. So long as the lists are short, which we */
+/* try to ensure via small bin ranges, there is little wasted effort.) */
+
+static mchunkptr malloc_find_space(unsigned int nb)
+{
+ mbinptr b;
+
+ /* first, re-adjust max used bin */
+
+ while (malloc_maxbin >= FIRSTBIN &&
+ malloc_maxbin->hd.bk == &(malloc_maxbin->hd))
+ {
+ malloc_maxbin->dirty = 0;
+ --malloc_maxbin;
+ }
+
+ for (b = malloc_maxbin; b >= FIRSTBIN; --b)
+ {
+ UPDATE_STATS(++n_malloc_bins);
+
+ if (b->dirty)
+ {
+ mchunkptr h = &(b->hd); /* head of list */
+ mchunkptr p = h->fd; /* chunk traverser */
+
+ while (p != h)
+ {
+ mchunkptr nextp = p->fd; /* save, in case of relinks */
+ int consolidated = 0; /* only unlink/relink if consolidated */
+
+ mchunkptr t;
+
+ UPDATE_STATS(++n_malloc_chunks);
+
+ while (!inuse(t = prev_chunk(p))) /* consolidate backward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(t, t->size + p->size);
+ p = t;
+ UPDATE_STATS (++n_consol);
+ }
+
+ while (!inuse(t = next_chunk(p))) /* consolidate forward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(p, p->size + t->size);
+ UPDATE_STATS (++n_consol);
+ }
+
+ if (consolidated)
+ {
+ if (p->size >= nb)
+ {
+ /* make it safe to unlink in malloc */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+ return p;
+ }
+ else
+ consollink(p);
+ }
+
+ p = nextp;
+
+ }
+
+ b->dirty = 0;
+
+ }
+ }
+
+ /* nothing available - sbrk some more */
+
+ return malloc_from_sys(nb);
+}
+
+
+
+/* Finally, the user-level functions */
+
+void* malloc(unsigned int bytes)
+{
+ unsigned int nb = request2size(bytes); /* padded request size */
+ mbinptr b = size2bin(nb); /* corresponding bin */
+ mchunkptr hd = &(b->hd); /* head of its list */
+ mchunkptr p = hd->fd; /* chunk traverser */
+
+ UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins));
+
+ /* Try a (near) exact match in own bin */
+ /* clean out unusable but consolidatable chunks in bin while traversing */
+
+ while (p != hd)
+ {
+ UPDATE_STATS(++n_malloc_chunks);
+ if (p->size >= nb)
+ goto found;
+ else /* try to consolidate; same code as malloc_find_space */
+ {
+ mchunkptr nextp = p->fd; /* save, in case of relinks */
+ int consolidated = 0; /* only unlink/relink if consolidated */
+
+ mchunkptr t;
+
+ while (!inuse(t = prev_chunk(p))) /* consolidate backward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(t, t->size + p->size);
+ p = t;
+ UPDATE_STATS (++n_consol);
+ }
+
+ while (!inuse(t = next_chunk(p))) /* consolidate forward */
+ {
+ if (!consolidated) { consolidated = 1; unlink(p); }
+ if (t == nextp) nextp = t->fd;
+ unlink(t);
+ set_size(p, p->size + t->size);
+ UPDATE_STATS (++n_consol);
+ }
+
+ if (consolidated)
+ {
+ if (p->size >= nb)
+ {
+ /* make it safe to unlink again below */
+ UPDATE_STATS(++n_avail);
+ p->fd = p->bk = p;
+ goto found;
+ }
+ else
+ consollink(p);
+ }
+
+ p = nextp;
+
+ }
+ }
+
+ b->dirty = 0; /* true if got here */
+
+ /* Scan bigger bins for a victim */
+
+ while (++b <= malloc_maxbin)
+ {
+ UPDATE_STATS(++n_malloc_bins);
+ if ((p = b->hd.bk) != &(b->hd)) /* no need to check size */
+ goto found;
+ }
+
+ /* Consolidate or sbrk */
+
+ p = malloc_find_space(nb);
+
+ if (p == 0) return 0; /* allocation failure */
+
+ found: /* Use what we found */
+
+ unlink(p);
+ split(p, nb);
+ UPDATE_STATS(do_malloc_stats(p));
+ return chunk2mem(p);
+}
+
+
+
+
+void free(void* mem)
+{
+ if (mem != 0)
+ {
+ mchunkptr p = mem2chunk(mem);
+ UPDATE_STATS(do_free_stats(p));
+ frontlink(p);
+ }
+}
+
+
+void* calloc(unsigned int n, unsigned int elem_size)
+{
+ unsigned int sz = n * elem_size;
+ void* p = malloc(sz);
+ bzero(p, sz);
+ return p;
+};
+
+/* This is here for compatibility with older systems */
+void cfree(void *mem)
+{
+ free(mem);
+}
+
+
+unsigned int malloc_usable_size(void* mem)
+{
+ if (mem == 0)
+ return 0;
+ else
+ {
+ mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ);
+ unsigned int sz = p->size & ~(INUSE);
+ if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ)))
+ return 0;
+ else
+ return sz - MALLOC_MIN_OVERHEAD;
+ }
+}
+
+
+
+void* realloc(void* mem, unsigned int bytes)
+{
+ if (mem == 0)
+ return malloc(bytes);
+ else
+ {
+ unsigned int nb = request2size(bytes);
+ mchunkptr p = mem2chunk(mem);
+ unsigned int oldsize = p->size;
+ int room;
+ mchunkptr nxt;
+
+ UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize));
+
+ /* try to expand (even if already big enough), to clean up chunk */
+
+ while (!inuse(nxt = next_chunk(p)))
+ {
+ UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol));
+ unlink(nxt);
+ set_size(p, p->size + nxt->size);
+ }
+
+ room = p->size - nb;
+ if (room >= 0)
+ {
+ split(p, nb);
+ UPDATE_STATS(malloced_mem -= room);
+ return chunk2mem(p);
+ }
+ else /* do the obvious */
+ {
+ void* newmem;
+ set_inuse(p); /* don't let malloc consolidate us yet! */
+ newmem = malloc(nb);
+ bcopy(mem, newmem, oldsize - SIZE_SZ);
+ free(mem);
+ UPDATE_STATS(++n_reallocs_with_copy);
+ return newmem;
+ }
+ }
+}
+
+
+
+/* return a pointer to space with at least the alignment requested */
+
+void* memalign(unsigned int alignment, unsigned int bytes)
+{
+ mchunkptr p;
+ unsigned int nb = request2size(bytes);
+
+ /* find an alignment that both we and the user can live with: */
+ /* least common multiple guarantees mutual happiness */
+ unsigned int align = lcm(alignment, MALLOC_MIN_OVERHEAD);
+ unsigned int mask = align - 1;
+
+ /* call malloc with worst case padding to hit alignment; */
+ /* we will give back extra */
+
+ unsigned int req = nb + align + MINSIZE;
+ void* m = malloc(req);
+
+ if (m == 0) return m;
+
+ p = mem2chunk(m);
+
+ /* keep statistics on track */
+
+ UPDATE_STATS(--n_mallocs);
+ UPDATE_STATS(malloced_mem -= p->size);
+ UPDATE_STATS(requested_mem -= req);
+ UPDATE_STATS(requested_mem += bytes);
+
+ if (((int)(m) & (mask)) != 0) /* misaligned */
+ {
+
+ /* find an aligned spot inside chunk */
+
+ mchunkptr ap = (mchunkptr)(( ((int)(m) + mask) & -align) - SIZE_SZ);
+
+ unsigned int gap = (unsigned int)(ap) - (unsigned int)(p);
+ unsigned int room;
+
+ /* we need to give back leading space in a chunk of at least MINSIZE */
+
+ if (gap < MINSIZE)
+ {
+ /* This works since align >= MINSIZE */
+ /* and we've malloc'd enough total room */
+
+ ap = (mchunkptr)( (int)(ap) + align );
+ gap += align;
+ }
+
+ if (gap + nb > p->size) /* can't happen unless chunk sizes corrupted */
+ malloc_user_error();
+
+ room = p->size - gap;
+
+ /* give back leader */
+ set_size(p, gap);
+ consollink(p);
+
+ /* use the rest */
+ p = ap;
+ set_size(p, room);
+ }
+
+ /* also give back spare room at the end */
+
+ split(p, nb);
+ UPDATE_STATS(do_malloc_stats(p));
+ return chunk2mem(p);
+
+}
+
+#ifndef sun
+#include "getpagesize.h"
+#endif
+
+static unsigned int malloc_pagesize = 0;
+
+void* valloc(unsigned int bytes)
+{
+ if (malloc_pagesize == 0) malloc_pagesize = getpagesize();
+ return memalign (malloc_pagesize, bytes);
+}
+
+
+void malloc_stats()
+{
+#ifndef MALLOC_STATS
+}
+#else
+ int i;
+ mchunkptr p;
+ double nm = (double)(n_mallocs + n_reallocs);
+
+ fprintf(stderr, "\nmalloc statistics\n\n");
+
+ if (n_mallocs != 0)
+ fprintf(stderr, "requests = %10u total size = %10u\tave = %10u\n",
+ n_mallocs, requested_mem, requested_mem/n_mallocs);
+
+ if (n_mallocs != 0)
+ fprintf(stderr, "mallocs = %10u total size = %10u\tave = %10u\n",
+ n_mallocs, malloced_mem, malloced_mem/n_mallocs);
+
+ if (n_frees != 0)
+ fprintf(stderr, "frees = %10u total size = %10u\tave = %10u\n",
+ n_frees, freed_mem, freed_mem/n_frees);
+
+ if (n_mallocs-n_frees != 0)
+ fprintf(stderr, "in use = %10u total size = %10u\tave = %10u\n",
+ n_mallocs-n_frees, malloced_mem-freed_mem,
+ (malloced_mem-freed_mem) / (n_mallocs-n_frees));
+
+ if (max_inuse != 0)
+ fprintf(stderr, "max in use= %10u total size = %10u\tave = %10u\n",
+ max_inuse, max_used_mem, max_used_mem / max_inuse);
+
+ if (n_avail != 0)
+ fprintf(stderr, "available = %10u total size = %10u\tave = %10u\n",
+ n_avail, sbrked_mem - (malloced_mem-freed_mem),
+ (sbrked_mem - (malloced_mem-freed_mem)) / n_avail);
+
+ if (n_sbrks != 0)
+ fprintf(stderr, "sbrks = %10u total size = %10u\tave = %10u\n\n",
+ n_sbrks, sbrked_mem, sbrked_mem/ n_sbrks);
+
+ if (n_reallocs != 0)
+ fprintf(stderr, "reallocs = %10u with copy = %10u\n\n",
+ n_reallocs, n_reallocs_with_copy);
+
+
+ if (nm != 0)
+ {
+ fprintf(stderr, "chunks scanned per malloc = %6.3f\n",
+ n_malloc_chunks / nm);
+ fprintf(stderr, "bins scanned per malloc = %6.3f\n",
+ n_malloc_bins / nm);
+ fprintf(stderr, "splits per malloc = %6.3f\n",
+ n_split / nm);
+ fprintf(stderr, "consolidations per malloc = %6.3f\n",
+ n_consol / nm);
+ }
+
+ fprintf(stderr, "\nfree chunks:\n");
+ for (i = 0; i < MAXBIN; ++i)
+ {
+ p = av[i].hd.fd;
+ if (p != &(av[i].hd))
+ {
+ unsigned int count = 1;
+ unsigned int sz = p->size;
+ for (p = p->fd; p != &(av[i].hd); p = p->fd)
+ {
+ if (p->size == sz)
+ ++count;
+ else
+ {
+ fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count);
+ count = 1;
+ sz = p->size;
+ }
+ }
+
+ fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count);
+
+ }
+ }
+}
+#endif /* MALLOC_STATS */
+
+#endif /* NO_LIBGXX_MALLOC */
+
+
diff --git a/gnu/lib/libregex/test/getpagesize.h b/gnu/lib/libregex/test/getpagesize.h
new file mode 100644
index 0000000..32adae6
--- /dev/null
+++ b/gnu/lib/libregex/test/getpagesize.h
@@ -0,0 +1,25 @@
+#ifdef BSD
+#ifndef BSD4_1
+#define HAVE_GETPAGESIZE
+#endif
+#endif
+
+#ifndef HAVE_GETPAGESIZE
+
+#include <sys/param.h>
+
+#ifdef EXEC_PAGESIZE
+#define getpagesize() EXEC_PAGESIZE
+#else
+#ifdef NBPG
+#define getpagesize() NBPG * CLSIZE
+#ifndef CLSIZE
+#define CLSIZE 1
+#endif /* no CLSIZE */
+#else /* no NBPG */
+#define getpagesize() NBPC
+#endif /* no NBPG */
+#endif /* no EXEC_PAGESIZE */
+
+#endif /* not HAVE_GETPAGESIZE */
+
diff --git a/gnu/lib/libregex/test/iregex.c b/gnu/lib/libregex/test/iregex.c
new file mode 100644
index 0000000..1ff12b6
--- /dev/null
+++ b/gnu/lib/libregex/test/iregex.c
@@ -0,0 +1,164 @@
+/* Main program for interactive testing. For maximum output, compile
+ this and regex.c with -DDEBUG. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "regex.h"
+
+/* Don't bother to guess about <string.h> vs <strings.h>, etc. */
+extern int strlen ();
+
+#define BYTEWIDTH 8
+
+extern void printchar ();
+extern char upcase[];
+
+static void scanstring ();
+static void print_regs ();
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ struct re_pattern_buffer buf;
+ char fastmap[(1 << BYTEWIDTH)];
+
+ /* Allow a command argument to specify the style of syntax. You can
+ use the `syntax' program to decode integer syntax values. */
+ if (argc > 1)
+ re_set_syntax (atoi (argv[1]));
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+
+ for (;;)
+ {
+ char pat[500], str[500];
+ struct re_registers regs;
+
+ /* Some C compilers don't like `char pat[500] = ""'. */
+ pat[0] = 0;
+
+ printf ("Pattern (%s) = ", pat);
+ gets (pat);
+ scanstring (pat);
+
+ if (feof (stdin))
+ {
+ putchar ('\n');
+ exit (0);
+ }
+
+ if (*pat)
+ {
+ re_compile_pattern (pat, strlen (pat), &buf);
+ re_compile_fastmap (&buf);
+#ifdef DEBUG
+ print_compiled_pattern (&buf);
+#endif
+ }
+
+ printf ("String = ");
+ gets (str); /* Now read the string to match against */
+ scanstring (str);
+
+ i = re_match (&buf, str, strlen (str), 0, &regs);
+ printf ("Match value %d.\t", i);
+ if (i >= 0)
+ print_regs (regs);
+ putchar ('\n');
+
+ i = re_search (&buf, str, strlen (str), 0, strlen (str), &regs);
+ printf ("Search value %d.\t", i);
+ if (i >= 0)
+ print_regs (regs);
+ putchar ('\n');
+ }
+
+ /* We never get here, but what the heck. */
+ return 0;
+}
+
+void
+scanstring (s)
+ char *s;
+{
+ char *write = s;
+
+ while (*s != '\0')
+ {
+ if (*s == '\\')
+ {
+ s++;
+
+ switch (*s)
+ {
+ case '\0':
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ *write = *s++ - '0';
+
+ if ('0' <= *s && *s <= '9')
+ {
+ *write = (*write << 3) + (*s++ - '0');
+ if ('0' <= *s && *s <= '9')
+ *write = (*write << 3) + (*s++ - '0');
+ }
+ write++;
+ break;
+
+ case 'n':
+ *write++ = '\n';
+ s++;
+ break;
+
+ case 't':
+ *write++ = '\t';
+ s++;
+ break;
+
+ default:
+ *write++ = *s++;
+ break;
+ }
+ }
+ else
+ *write++ = *s++;
+ }
+
+ *write++ = '\0';
+}
+
+/* Print REGS in human-readable form. */
+
+void
+print_regs (regs)
+ struct re_registers regs;
+{
+ int i, end;
+
+ printf ("Registers: ");
+
+ if (regs.num_regs == 0 || regs.start[0] == -1)
+ {
+ printf ("(none)");
+ }
+ else
+ {
+ /* Find the last register pair that matched. */
+ for (end = regs.num_regs - 1; end >= 0; end--)
+ if (regs.start[end] != -1)
+ break;
+
+ printf ("[%d ", regs.start[0]);
+ for (i = 1; i <= end; i++)
+ printf ("(%d %d) ", regs.start[i], regs.end[i]);
+ printf ("%d]", regs.end[0]);
+ }
+}
diff --git a/gnu/lib/libregex/test/main.c b/gnu/lib/libregex/test/main.c
new file mode 100644
index 0000000..da4536d
--- /dev/null
+++ b/gnu/lib/libregex/test/main.c
@@ -0,0 +1,49 @@
+/* Main routine for running various tests. Meant only to be linked with
+ all the auxiliary test source files, with `test' undefined. */
+
+#include "test.h"
+
+test_type t = all_test;
+
+
+/* Use this to run the tests we've thought of. */
+
+int
+main ()
+{
+ switch (t)
+ {
+ case all_test:
+ test_regress ();
+ test_others ();
+ test_posix_basic ();
+ test_posix_extended ();
+ test_posix_interface ();
+ break;
+
+ case other_test:
+ test_others ();
+ break;
+
+ case posix_basic_test:
+ test_posix_basic ();
+ break;
+
+ case posix_extended_test:
+ test_posix_extended ();
+ break;
+
+ case posix_interface_test:
+ test_posix_interface ();
+ break;
+
+ case regress_test:
+ test_regress ();
+ break;
+
+ default:
+ fprintf (stderr, "Unknown test %d.\n", t);
+ }
+
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/malloc-test.c b/gnu/lib/libregex/test/malloc-test.c
new file mode 100644
index 0000000..7e27a15
--- /dev/null
+++ b/gnu/lib/libregex/test/malloc-test.c
@@ -0,0 +1,47 @@
+
+
+typedef struct {
+ unsigned *bits;
+ unsigned size;
+} bits_list_type;
+
+#define BYTEWIDTH 8
+#define NULL 0
+
+#define BITS_BLOCK_SIZE (sizeof (unsigned) * BYTEWIDTH)
+#define BITS_BLOCK(position) ((position) / BITS_BLOCK_SIZE)
+#define BITS_MASK(position) (1 << ((position) % BITS_BLOCK_SIZE))
+
+static unsigned
+init_bits_list (bits_list_ptr)
+ bits_list_type *bits_list_ptr;
+{
+ bits_list_ptr->bits = NULL;
+ bits_list_ptr->bits = (unsigned *) malloc (sizeof (unsigned));
+
+ if (bits_list_ptr->bits == NULL)
+ return 0;
+
+ bits_list_ptr->bits[0] = (unsigned)0;
+ bits_list_ptr->size = BITS_BLOCK_SIZE;
+
+ return 1;
+}
+
+
+main()
+{
+ bits_list_type dummy;
+ bits_list_type dummy_1;
+ bits_list_type dummy_2;
+ bits_list_type dummy_3;
+
+ init_bits_list (&dummy);
+printf("init 1\n");
+ init_bits_list (&dummy_1);
+printf("init 2\n");
+ init_bits_list (&dummy_2);
+printf("init 3\n");
+ init_bits_list (&dummy_3);
+printf("init 4\n");
+}
diff --git a/gnu/lib/libregex/test/other.c b/gnu/lib/libregex/test/other.c
new file mode 100644
index 0000000..1023fc6
--- /dev/null
+++ b/gnu/lib/libregex/test/other.c
@@ -0,0 +1,503 @@
+/* other.c: test (not exhaustively) non-POSIX regular expressions. */
+
+#include "test.h"
+
+void
+test_others ()
+{
+ struct re_registers regs;
+
+ printf ("\nStarting non-POSIX tests.\n");
+ t = other_test;
+
+ test_should_match = true;
+
+ /* The big question: does the group participate in the match, or match
+ the empty string? */
+ re_set_syntax (RE_NO_BK_PARENS);
+ test_match ("(a*)*ab", "ab");
+ TEST_REGISTERS ("(a*)*ab", "ab", 0, 2, 0, 0, -1, -1);
+ test_match ("(a*)*", "");
+ TEST_REGISTERS ("(a*)*ab", "ab", 0, 0, 0, 0, -1, -1);
+
+ /* This tests finding the highest and lowest active registers. */
+ test_match ("(a(b)c(d(e)f)g)h(i(j)k(l(m)n)o)\\1\\2\\3\\4\\5\\6\\7\\8",
+ "abcdefghijklmnoabcdefgbdefeijklmnojlmnm");
+
+ /* Test that \< and \> match at the beginning and end of the string. */
+ test_match ("\\<abc\\>", "abc");
+
+ /* May as well test \` and \' while we're at it. */
+ test_match ("\\`abc\\'", "abc");
+
+#if 0
+ /* Test backreferencing and the fastmap -- which doesn't work. */
+ test_fastmap ("(a)*\\1", "a", 0, 0);
+#endif
+
+ /* But at least we shouldn't search improperly. */
+ test_search_return (-1, "(a)\\1", "");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ MATCH_SELF("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+ MATCH_SELF ("a^");
+ MATCH_SELF ("a^b");
+ MATCH_SELF ("$a");
+ MATCH_SELF ("a$b");
+
+ re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
+ test_match ("[\\^a]", "a");
+ test_match ("[\\^a]", "^");
+
+ /* These op characters should be ordinary if RE_CONTEXT_INVALID_OPS
+ isn't set. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_BRACES | RE_INTERVALS
+ | RE_NO_BK_PARENS);
+ MATCH_SELF ("*");
+ test_match ("a|*", "*");
+ test_match ("(*)", "*");
+
+ MATCH_SELF ("+");
+ test_match ("a|+", "+");
+ test_match ("(+)", "+");
+
+ MATCH_SELF ("?");
+ test_match ("a|?", "?");
+ test_match ("(?)", "?");
+
+ MATCH_SELF ("{1}");
+ test_match ("a|{1}", "a");
+ test_match ("a|{1}", "{1}");
+ test_match ("({1})", "{1}");
+
+ test_match ("\\{", "{");
+
+
+ re_set_syntax (RE_LIMITED_OPS);
+ MATCH_SELF ("|");
+ MATCH_SELF ("a|");
+ MATCH_SELF ("a|");
+ MATCH_SELF ("a||");
+ MATCH_SELF ("a||");
+ MATCH_SELF ("(|)");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+#if 0
+ /* Newline is no longer special for anchors (16 Sep 92). --karl */
+ test_match_2 ("a\n^b", "a", "\nb");
+ test_match_2 ("a$\nb", "a\n", "b");
+#endif
+
+ /* Test grouping. */
+ re_set_syntax (RE_NO_BK_PARENS);
+
+ test_match ("()", "");
+ test_fastmap ("()", "", 0, 0);
+ TEST_REGISTERS ("()", "", 0, 0, 0, 0, -1, -1);
+
+ test_match ("((((((((()))))))))", "");
+ test_fastmap ("((((((((()))))))))", "", 0, 0);
+ test_match ("a()b", "ab");
+ TEST_REGISTERS ("a()b", "ab", 0, 2, 1, 1, -1, -1);
+
+ test_match ("(((((((((())))))))))", "");
+ test_fastmap ("(((((((((())))))))))", "", 0, 0);
+
+ test_match ("()*", "");
+ TEST_REGISTERS ("()*", "", 0, 0, 0, 0, -1, -1); /* empty string */
+ test_match ("(())*", "");
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS);
+ test_match ("*", "");
+
+ re_set_syntax (RE_INTERVALS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES);
+ test_match ("{1}", ""); /* Should remain an interval. */
+ MATCH_SELF ("{1"); /* Not a valid interval. */
+
+ re_set_syntax (RE_NEWLINE_ALT);
+ test_match ("a\nb", "a");
+ test_match ("a\nb", "b");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ test_match ("^a", "a");
+ test_match ("(^a)", "a");
+ test_match ("(a|^b)", "b");
+ test_match ("a$", "a");
+ test_match ("(a$)", "a");
+ test_match ("a$|b", "a");
+
+ /* You should be able to have empty alternatives if RE_NO_EMPTY_ALTS
+ isn't set. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+
+ test_match ("|", "");
+ test_match ("^|a", "");
+ test_match ("^|a", "a");
+ test_match ("a|", "");
+ test_match ("a|", "a");
+ test_match ("a|$", "");
+ test_match ("a|$", "a");
+ test_match ("a||b", "a");
+ test_match ("a||b", "");
+ test_match ("a||b", "b");
+ test_match ("(|a)", "");
+ test_match ("(|a)", "a");
+ test_match ("(a|)", "");
+ test_match ("(a|)", "a");
+
+ TEST_SEARCH ("a|$", "xa", 0, 2);
+ TEST_SEARCH ("a|$", "x", 0, 1);
+ TEST_SEARCH ("$|b", "x", 0, 1);
+ TEST_SEARCH ("$|b", "xb", 0, 2);
+ TEST_SEARCH ("c(a|$)", "xca", 0, 3);
+ TEST_SEARCH ("c(a|$)", "xc", 0, 2);
+ TEST_SEARCH ("c($|b)", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b)", "xc", 0, 2);
+ TEST_SEARCH ("c($|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("c(a$|$)", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("(a$|b$)|$", "x", 0, 1);
+ TEST_SEARCH ("(a$|b$)|$", "xa", 0, 2);
+ TEST_SEARCH ("(a$|b$)|$", "xb", 0, 2);
+ TEST_SEARCH ("(a$|$)|c$", "x", 0, 1);
+ TEST_SEARCH ("(a$|$)|c$", "xa", 0, 2);
+ TEST_SEARCH ("(a$|$)|c$", "xc", 0, 2);
+ TEST_SEARCH ("($|b$)|c$", "x", 0, 1);
+ TEST_SEARCH ("($|b$)|c$", "xb", 0, 2);
+ TEST_SEARCH ("($|b$)|c$", "xc", 0, 2);
+ TEST_SEARCH ("c$|(a$|$)", "x", 0, 1);
+ TEST_SEARCH ("c$|(a$|$)", "xa", 0, 2);
+ TEST_SEARCH ("c$|(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("c$|($|b$)", "x", 0, 1);
+ TEST_SEARCH ("c$|($|b$)", "xb", 0, 2);
+ TEST_SEARCH ("c$|($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("$|(a$|b$)", "x", 0, 1);
+ TEST_SEARCH ("$|(a$|b$)", "xa", 0, 2);
+ TEST_SEARCH ("$|(a$|b$)", "xb", 0, 2);
+ TEST_SEARCH ("c(a$|b$)|$", "x", 0, 1);
+ TEST_SEARCH ("c(a$|b$)|$", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|b$)|$", "xcb", 0, 3);
+ TEST_SEARCH ("c(a$|$)|d$", "xc", 0, 2);
+ TEST_SEARCH ("c(a$|$)|d$", "xca", 0, 3);
+ TEST_SEARCH ("c(a$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("c($|b$)|d$", "xc", 0, 2);
+ TEST_SEARCH ("c($|b$)|d$", "xcb", 0, 3);
+ TEST_SEARCH ("c($|b$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xdc", 0, 3);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xde", 0, 3);
+ TEST_SEARCH ("d(c$|e((a$|$)))", "xdea", 0, 4);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xdc", 0, 3);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xde", 0, 3);
+ TEST_SEARCH ("d(c$|e(($|b$)))", "xdeb", 0, 4);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xd", 0, 2);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xdea", 0, 4);
+ TEST_SEARCH ("d($|e((a$|b$)))", "xdeb", 0, 4);
+ TEST_SEARCH ("a(b$|c$)|$", "x", 0, 1);
+ TEST_SEARCH ("a(b$|c$)|$", "xab", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|$", "xac", 0, 3);
+ TEST_SEARCH ("a(b$|$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("a(b$|$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("a(b$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("a($|c$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("a($|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("a($|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|a(b$|$)", "xab", 0, 3);
+ TEST_SEARCH ("d$|a($|c$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|a($|c$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|a($|c$)", "xac", 0, 3);
+ TEST_SEARCH ("$|a(b$|c$)", "x", 0, 1);
+ TEST_SEARCH ("$|a(b$|c$)", "xab", 0, 3);
+ TEST_SEARCH ("$|a(b$|c$)", "xac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xab", 0, 3);
+ TEST_SEARCH ("(a)(b$|$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("(a)($|c$)|d$", "xa", 0, 2);
+ TEST_SEARCH ("(a)($|c$)|d$", "xac", 0, 3);
+ TEST_SEARCH ("(a)($|c$)|d$", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|$)", "xab", 0, 3);
+ TEST_SEARCH ("d$|(a)($|c$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|(a)($|c$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|(a)($|c$)", "xac", 0, 3);
+ TEST_SEARCH ("$|(a)(b$|c$)", "x", 0, 1);
+ TEST_SEARCH ("$|(a)(b$|c$)", "xab", 0, 3);
+ TEST_SEARCH ("$|(a)(b$|c$)", "xac", 0, 3);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "x", 0, 1);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xc", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|$))", "xa", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "x", 0, 1);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xc", 0, 2);
+ TEST_SEARCH ("d$|(c$|($|b$))", "xb", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "x", 0, 1);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xd", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xa", 0, 2);
+ TEST_SEARCH ("d$|($|(a$|b$))", "xb", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "x", 0, 1);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xc", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xa", 0, 2);
+ TEST_SEARCH ("$|(c$|(a$|b$))", "xb", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xc", 0, 2);
+ TEST_SEARCH ("d$|c(a$|$)", "xca", 0, 3);
+ TEST_SEARCH ("d$|c($|b$)", "xd", 0, 2);
+ TEST_SEARCH ("d$|c($|b$)", "xc", 0, 2);
+ TEST_SEARCH ("d$|c($|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("$|c(a$|b$)", "x", 0, 1);
+ TEST_SEARCH ("$|c(a$|b$)", "xca", 0, 3);
+ TEST_SEARCH ("$|c(a$|b$)", "xcb", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xec", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|$)))", "xeca", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xed", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xec", 0, 3);
+ TEST_SEARCH ("e(d$|c(($|b$)))", "xecb", 0, 4);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xe", 0, 2);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xeca", 0, 4);
+ TEST_SEARCH ("e($|c((a$|b$)))", "xecb", 0, 4);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xc", 0, 2);
+ TEST_SEARCH ("ed$|(c((a$|$)))", "xca", 0, 3);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xed", 0, 3);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xc", 0, 2);
+ TEST_SEARCH ("ed$|(c(($|b$)))", "xcb", 0, 3);
+ TEST_SEARCH ("$|(c((a$|b$)))", "x", 0, 1);
+ TEST_SEARCH ("$|(c((a$|b$)))", "xca", 0, 3);
+ TEST_SEARCH ("$|(c((a$|b$)))", "xcb", 0, 3);
+ TEST_SEARCH ("d$|($|(a|b)$)", "x", 0, 1);
+ TEST_SEARCH ("d$|($|(a|b)$)", "xa", 0, 2);
+ TEST_SEARCH ("d$|($|(a|b)$)", "xb", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "x", 0, 1);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xc", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xa", 0, 2);
+ TEST_SEARCH ("$|(c$|(a|b)$)", "xb", 0, 2);
+
+ re_set_syntax (0);
+ test_match ("[^\n]", "a");
+ test_match ("[^a]", "\n");
+
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+ test_case_fold ("[!-`]", "A");
+ test_case_fold ("[!-`]", "a");
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_NO_BK_VBAR | RE_NO_BK_PARENS
+ | RE_NO_BK_BRACES | RE_INTERVALS);
+ valid_nonposix_pattern ("()^a");
+ valid_nonposix_pattern ("()\\1^a");
+
+ /* Per Cederqvist (cedar@lysator.liu.se) bug. */
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* One `a' before the \n and 638 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* No a's before the \n and 639 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* One `a' before the \n and 639 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "a\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ /* No a's before the \n and 640 a's after it. */
+ test_search_return (0, "\\(.*\\)\n\\(\\(.\\|\n\\)*\\)$", "\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ TEST_SEARCH ("^(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(a$)$", "ba", 0, 2);
+ test_match ("a|$b", "$b");
+
+ /* Mike's curiosity item. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS);
+ test_all_registers ("(foo|foobar)(foo|bar)*\\1(foo|bar)*",
+ "foobarfoobar", "",
+ 0, 12, 0, 3, 3, 6, 9, 12, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1);
+
+ /* Another one from Mike. */
+ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");
+
+ /* And another. */
+ test_match("(foo|foobar)(bar|barfoo)?\\1", "foobarfoobar");
+
+ re_set_syntax (RE_NO_BK_PARENS | RE_INTERVALS | RE_NO_BK_VBAR
+ | RE_NO_BK_BRACES); /* xx get new ones from ext.*/
+ test_match ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "bb");
+ test_all_registers ("((a{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)*", "", "bb",
+ 0, 2, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ test_match ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "b");
+ test_all_registers ("((a+?*{0,}{0,0}()\\3\\b\\B\\<\\>\\`\\')|b)", "", "b",
+ 0, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ /* Valid anchoring. */
+ /* See generic_test.c and extended_test.c for more search
+ tests. xx Not sure all these tests are represented in the
+ search tests. */
+
+ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
+ valid_nonposix_pattern
+ ("(((((((((((((((((((((((((((((((((^a)))))))))))))))))))))))))))))))))");
+ valid_nonposix_pattern
+ ("(((((((((((((((((((((((((((((((((a$)))))))))))))))))))))))))))))))))");
+ valid_nonposix_pattern ("\\b\\B\\<\\>\\`\\'^a");
+ valid_nonposix_pattern ("a$\\b\\B\\<\\>\\`\\'");
+ valid_nonposix_pattern ("(^a)");
+ valid_nonposix_pattern ("(a$)");
+ valid_nonposix_pattern ("(^a)b");
+ valid_nonposix_pattern ("b(a$)");
+ valid_nonposix_pattern ("(^a|^b)c");
+ valid_nonposix_pattern ("c(a$|b$)");
+ valid_nonposix_pattern ("(^a|^b)|^c");
+ valid_nonposix_pattern ("(a$|b$)|c$");
+ valid_nonposix_pattern ("^c|(^a|^b)");
+ valid_nonposix_pattern ("c$|(a$|b$)");
+ valid_nonposix_pattern ("(^a|^b)c|^d");
+ valid_nonposix_pattern ("c(a$|b$)|d$");
+ valid_nonposix_pattern ("(((^a|^b))c|^d)e");
+ valid_nonposix_pattern ("(c((a|b))|d)e$");
+ valid_nonposix_pattern ("^d(c|e((a|b)))");
+ valid_nonposix_pattern ("d(c$|e((a$|b$)))");
+ valid_nonposix_pattern ("(((^a|^b))c)|^de");
+ valid_nonposix_pattern ("(((a|b))c$)|de$");
+
+ valid_nonposix_pattern ("((a$)$)$");
+ valid_nonposix_pattern ("^(^(^a))");
+
+ valid_nonposix_pattern ("^de|^(c((a|b)))");
+ valid_nonposix_pattern ("^de|(^c((a|b)))");
+ valid_nonposix_pattern ("de$|(c((a|b)$))");
+ valid_nonposix_pattern ("de$|(c((a|b))$)");
+ valid_nonposix_pattern ("de$|(c((a|b)))$");
+
+ valid_nonposix_pattern ("^a(b|c)|^d");
+ valid_nonposix_pattern ("a(b$|c$)|d$");
+ valid_nonposix_pattern ("^d|^a(b|c)");
+ valid_nonposix_pattern ("d$|a(b$|c$)");
+ valid_nonposix_pattern ("^d|^(b|c)a");
+ valid_nonposix_pattern ("d$|(b|c)a$");
+ valid_nonposix_pattern ("^(a)(b|c)|^d");
+ valid_nonposix_pattern ("(a)(b|c)$|d$");
+ valid_nonposix_pattern ("(^a)(b|c)|^d");
+ valid_nonposix_pattern ("(a)(b$|c$)|d$");
+ valid_nonposix_pattern ("^d|^(b|c)(a)");
+ valid_nonposix_pattern ("d$|(b|c)(a)$");
+ valid_nonposix_pattern ("^d|(^b|^c)(a)");
+ valid_nonposix_pattern ("d$|(b|c)(a$)");
+ valid_nonposix_pattern ("^d|^(a)(b|c)");
+ valid_nonposix_pattern ("^d|(^a)(b|c)");
+ valid_nonposix_pattern ("d$|(a)(b$|c$)");
+ valid_nonposix_pattern ("((^a|^b)|^c)|^d");
+ valid_nonposix_pattern ("d$|(c$|(a$|b$))");
+
+
+ /* Tests shouldn't match. */
+ test_should_match = false;
+
+ /* Test that RE_CONTEXT_INVALID_OPS has precedence over
+ RE_CONTEXT_INDEP_OPS. */
+
+ re_set_syntax (RE_CONTEXT_INDEP_OPS | RE_CONTEXT_INVALID_OPS
+ | RE_NO_BK_VBAR | RE_NO_BK_PARENS
+ | RE_NO_BK_BRACES | RE_INTERVALS);
+ INVALID_PATTERN ("*");
+ INVALID_PATTERN ("^*");
+ INVALID_PATTERN ("a|*");
+ INVALID_PATTERN ("(*)");
+
+ INVALID_PATTERN ("^+");
+ INVALID_PATTERN ("+");
+ INVALID_PATTERN ("a|+");
+ INVALID_PATTERN ("(+)");
+
+ INVALID_PATTERN ("^?");
+ INVALID_PATTERN ("?");
+ INVALID_PATTERN ("a|?");
+ INVALID_PATTERN ("(?)");
+
+ INVALID_PATTERN ("^{1}");
+ INVALID_PATTERN ("{1}");
+ INVALID_PATTERN ("a|{1}");
+ INVALID_PATTERN ("({1})");
+
+#if 0
+ /* No longer have this syntax option -- POSIX says empty alternatives
+ are undefined as of draft 11.2. */
+
+ /* You can't have empty alternatives if RE_NO_EMPTY_ALTS is set. */
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
+
+ INVALID_PATTERN ("|");
+ INVALID_PATTERN ("^|a");
+ INVALID_PATTERN ("a|");
+ INVALID_PATTERN ("a||");
+ INVALID_PATTERN ("a||b");
+ INVALID_PATTERN ("(|a)");
+ INVALID_PATTERN ("(a|)");
+ INVALID_PATTERN ("(a|)");
+
+
+ /* Test above with `\(' and `\)'. */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_EMPTY_ALTS);
+ INVALID_PATTERN ("\\(|a\\)");
+ INVALID_PATTERN ("\\(a|\\)");
+
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_ALTS);
+ INVALID_PATTERN ("(|)()$|d$");
+#endif
+
+ /* Test grouping. */
+ test_match ("()", "a");
+
+ /* Test backslashed intervals that are CONTEXTly invalid if have
+ nothing on which to operate. */
+
+ re_set_syntax (RE_INTERVALS | RE_CONTEXT_INVALID_OPS);
+ INVALID_PATTERN ("\\{1\\}");
+
+ re_set_syntax (0);
+ test_match ("z-a", "a");
+
+ re_set_syntax (RE_BK_PLUS_QM);
+ INVALID_PATTERN ("a*\\");
+
+ re_set_syntax (0);
+ INVALID_PATTERN ("a*\\");
+
+ re_set_syntax (RE_BACKSLASH_ESCAPE_IN_LISTS);
+ INVALID_PATTERN ("[\\");
+
+#if 0
+ /* Empty groups are always ok now. (13 Sep 92) */
+ re_set_syntax (RE_NO_BK_VBAR | RE_NO_BK_PARENS | RE_NO_EMPTY_GROUPS);
+ INVALID_PATTERN ("(|)()$|d$");
+#endif
+
+ printf ("\nFinished non-POSIX tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/printchar.c b/gnu/lib/libregex/test/printchar.c
new file mode 100644
index 0000000..1b756f4
--- /dev/null
+++ b/gnu/lib/libregex/test/printchar.c
@@ -0,0 +1,14 @@
+void
+printchar (c)
+ char c;
+{
+ if (c < 040 || c >= 0177)
+ {
+ putchar ('\\');
+ putchar (((c >> 6) & 3) + '0');
+ putchar (((c >> 3) & 7) + '0');
+ putchar ((c & 7) + '0');
+ }
+ else
+ putchar (c);
+}
diff --git a/gnu/lib/libregex/test/psx-basic.c b/gnu/lib/libregex/test/psx-basic.c
new file mode 100644
index 0000000..487c604
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-basic.c
@@ -0,0 +1,253 @@
+/* psx-basic.c: Test POSIX basic regular expressions. */
+
+#include "test.h"
+
+
+void
+test_posix_basic ()
+{
+ /* Intervals can only match up to RE_DUP_MAX occurences of anything. */
+ char dup_max_plus_one[6];
+ sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);
+
+ printf ("\nStarting POSIX basic tests.\n");
+ t = posix_basic_test;
+
+ re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_BASIC);
+
+ test_posix_generic ();
+
+ printf ("\nContinuing POSIX basic tests.\n");
+
+/* Grouping tests that are not the same. */
+
+ test_should_match = false;
+ invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("a)"));
+
+ test_should_match = true;
+ /* Special characters. */
+ MATCH_SELF ("*");
+ test_match ("\\(*\\)", "*");
+ test_match ("\\(^*\\)", "*");
+ test_match ("**", "***");
+ test_match ("***", "****");
+
+ MATCH_SELF ("{"); /* of extended... */
+ MATCH_SELF ("()"); /* also non-Posix. */
+ MATCH_SELF ("a+");
+ MATCH_SELF ("a?");
+ MATCH_SELF ("a|b");
+ MATCH_SELF ("a|"); /* No alternations, */
+ MATCH_SELF ("|a"); /* so OK if empty. */
+ MATCH_SELF ("a||");
+ test_match ("\\(|a\\)", "|a");
+ test_match ("\\(a|\\)", "a|");
+ test_match ("a\\+", "a+");
+ test_match ("a\\?", "a?");
+ test_match ("a\\|b", "a|b");
+ test_match ("^*", "*");
+ test_match ("^+", "+");
+ test_match ("^?", "?");
+ test_match ("^{", "{");
+ /* Valid subexpressions
+ (empty) in basic only. */
+ test_match ("\\(\\)", "");
+
+ test_match ("a\\(\\)", "a");
+ test_match ("\\(\\)b", "b");
+ test_match ("a\\(\\)b", "ab");
+ TEST_REGISTERS ("a\\(\\)b", "ab", 0, 2, 1, 1, -1, -1);
+
+ test_match ("\\(\\)*", "");
+ test_match ("\\(\\(\\)\\)*", "");
+ /* Valid back references. */
+
+ /* N.B.: back references to subexpressions that include a * are
+ undefined in the spec. The tests are in here to see if we handle
+ the situation consistently, but if it fails any of them, it doesn't
+ matter. */
+
+ test_match ("\\(\\)\\1", "");
+ TEST_REGISTERS ("\\(\\)\\1", "", 0, 0, 0, 0, -1, -1);
+
+ test_match ("\\(\\(\\)\\)\\(\\)\\2", "");
+
+ test_match ("\\(a\\)\\1", "aa");
+ TEST_REGISTERS ("\\(a\\)\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1", "xaax", 1, 3, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a\\)\\)\\1", "aa");
+ test_match ("\\(a\\)\\(b\\)\\2\\1", "abba");
+
+ test_match ("\\(a\\)*\\1", "aa");
+ TEST_REGISTERS ("\\(a\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)*\\1", "xaax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a\\)\\2b\\)*", "aab");
+ TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "aab", 0, 3, 0, 3, 0, 1);
+ TEST_REGISTERS ("\\(\\(a\\)\\2b\\)*", "xaabx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*\\)*\\1", "");
+ test_match ("\\(a*\\)*\\1", "aa");
+ TEST_REGISTERS ("\\(a*\\)*\\1", "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)*\\1", "xaax", 0, 0, 0, 0, -1, -1);
+
+ test_match ("\\(a*\\)*\\1", "");
+ test_match ("\\(a*\\)*\\1", "aa");
+ test_match ("\\(\\(a*\\)*\\)*\\1", "aa");
+ test_match ("\\(ab*\\)*\\1", "abab");
+ TEST_REGISTERS ("\\(ab*\\)*\\1", "abab", 0, 4, 0, 2, -1, -1);
+ TEST_REGISTERS ("\\(ab*\\)*\\1", "xababx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*\\)ab\\1", "aaba");
+ TEST_REGISTERS ("\\(a*\\)ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
+
+ test_match ("\\(a*\\)*ab\\1", "aaba");
+ TEST_REGISTERS ("\\(a*\\)*ab\\1", "aaba", 0, 4, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a*\\)*ab\\1", "xaabax", 1, 5, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2", "abb");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "abb", 0, 3, 2, 3, 2, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xabbx", 0, 0, -1, -1, -1, -1);
+
+ /* Different from above. */
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aa", 0, 2, 0, 1, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aba");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aba", 0, 3, 0, 2, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xabax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2", "aababa");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "aababa", 0, 6, 3, 5, 3, 4);
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2", "xaababax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aabaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabaa", 0, 5, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "aabbaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "aabbaa", 0, 6, 0, 4, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaabbaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2", "abaabaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "abaabaa", 0, 7, 2, 5, 2, 4);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2", "xaababaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\(\\(a*\\)b*\\)*a\\2", "aabaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "aabaaa", 0, 6, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*a\\)*\\2", "xaabaax", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "aabaaa", 0, 6, 0, 3, 0, 2);
+ TEST_REGISTERS ("\\(\\(a*\\)b*\\)*\\2a", "xaabaaax", 1, 7, 1, 4, 1, 3);
+
+ test_match ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab");
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "abaabaaaab", 0, 10, 2, 5, 2, 4);
+ /* We are matching the empty string here. */
+ TEST_REGISTERS ("\\(\\(a*\\)b\\)*\\2\\1", "xabaabaaaabx", 0, 0, -1, -1, -1, -1);
+
+ test_match ("\\(a*b\\)\\1", "abab");
+ test_match ("\\(a\\)\\1\\1", "aaa");
+ test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdacdc");
+
+ test_match ("\\(a\\)\\1*", "aaa");
+ TEST_REGISTERS ("\\(a\\)\\1*", "aaa", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1*", "xaaax", 1, 4, 1, 2, -1, -1);
+
+ test_match ("\\(a\\)\\{1,3\\}b\\1", "aba");
+ TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "aba", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\{1,3\\}b\\1", "xabax", 1, 4, 1, 2, -1, -1);
+
+ test_match ("\\(\\(a\\)\\2\\)*", "aaaa"); /* rms? */
+ TEST_REGISTERS ("\\(\\(a*b\\)\\2\\)*", "bbabab", 0, 6, 2, 6, 2, 4); /* rms? */
+
+ test_match ("\\(\\(a\\)\\1\\)*", "a1a1");
+
+ test_match ("\\(\\(a\\)\\2\\)\\1", "aaaa");
+
+ test_match ("\\(\\(a*\\)\\2\\)\\1", "aaaa");
+ TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "aaaa", 0, 4, 0, 2, 0, 1);
+ TEST_REGISTERS ("\\(\\(a*\\)\\2\\)\\1", "xaaaax", 0, 0, 0, 0, 0, 0);
+
+ test_match ("\\{1\\}", "{1}");
+ test_match ("^\\{1\\}", "{1}");
+
+ test_match ("\\(a\\)\\1\\{1,2\\}", "aaa");
+ TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "aaa", 0, 3, 0, 1, -1, -1);
+ TEST_REGISTERS ("\\(a\\)\\1\\{1,2\\}", "xaaax", 1, 4, 1, 2, -1, -1);
+
+
+ /* Per POSIX D11.1 p. 109, leftmost longest match. */
+
+ test_match (PARENS_TO_OPS ("(.*).*\\1"), "abcabc");
+
+
+ /* Per POSIX D11.1, p. 125, leftmost longest match. */
+
+ test_match (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ac*)c*d[ac]*\\1"), "acdacaaa",
+ 0, 8, 0, 1, -1, -1);
+
+ /* Anchors become ordinary, sometimes. */
+ MATCH_SELF ("a^");
+ MATCH_SELF ("$a");
+ MATCH_SELF ("$^");
+ test_fastmap ("$a^", "$", 0, 0);
+ test_match ("$^*", "$^^");
+ test_match ("\\($^\\)", "$^");
+ test_match ("$*", "$$");
+ /* xx -- known bug, solution pending test_match ("^^$", "^"); */
+ test_match ("$\\{0,\\}", "$$");
+ TEST_SEARCH ("^$*", "$$", 0, 2);
+ TEST_SEARCH ("^$\\{0,\\}", "$$", 0, 2);
+ MATCH_SELF ("2^10");
+ MATCH_SELF ("$HOME");
+ MATCH_SELF ("$1.35");
+
+
+ /* Basic regular expressions, continued; these don't match their strings. */
+ test_should_match = false;
+
+ invalid_pattern (REG_EESCAPE, "\\(a\\");
+ /* Invalid back references. */
+ test_match ("\\(a\\)\\1", "ab");
+ test_match ("\\(a\\)\\1\\1", "aab");
+ test_match ("\\(a\\)\\(b\\)\\2\\1", "abab");
+ test_match ("\\(a\\(c\\)d\\)\\1\\2", "acdc");
+ test_match ("\\(a*b\\)\\1", "abaab");
+ test_match ("\\(a\\)\\1*", "aaaaaaaaaab");
+ test_match ("\\(\\(a\\)\\1\\)*", "aaa");
+ invalid_pattern (REG_ESUBREG, "\\1");
+ invalid_pattern (REG_ESUBREG, "\\(a\\)\\2");
+ test_match ("\\(\\(a\\)\\2\\)*", "abaa");
+ test_match ("\\(\\(a\\)\\1\\)*", "a");
+ test_match ("\\(\\(a\\)\\2\\)\\1", "abaa");
+ test_match ("\\(\\(a*\\)\\2\\)\\1", "abaa");
+ /* Invalid intervals. */
+ invalid_pattern (REG_EBRACE, "a\\{");
+
+ invalid_pattern (REG_BADBR, "a\\{-1");
+ invalid_pattern (REG_BADBR, concat ("a\\{", (char *)dup_max_plus_one));
+ invalid_pattern (REG_BADBR, concat (concat ("a\\{", (char *)dup_max_plus_one), ","));
+ invalid_pattern (REG_BADBR, "a\\{1,0");
+
+ invalid_pattern (REG_EBRACE, "a\\{1");
+ invalid_pattern (REG_EBRACE, "a\\{0,");
+ invalid_pattern (REG_EBRACE, "a\\{0,1");
+ invalid_pattern (REG_EBRACE, "a\\{0,1}");
+
+ printf ("\nFinished POSIX basic tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-extend.c b/gnu/lib/libregex/test/psx-extend.c
new file mode 100644
index 0000000..14b8a5e
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-extend.c
@@ -0,0 +1,1244 @@
+/* psx-extend.c: Test POSIX extended regular expressions. */
+
+#include "test.h"
+
+
+void
+test_posix_extended ()
+{
+ /* Intervals can only match up to RE_DUP_MAX occurences of anything. */
+ char dup_max_plus_one[6];
+ sprintf (dup_max_plus_one, "%d", RE_DUP_MAX + 1);
+
+
+ printf ("\nStarting POSIX extended tests.\n");
+ t = posix_extended_test;
+
+ re_set_syntax (RE_SYNTAX_POSIX_MINIMAL_EXTENDED);
+
+ test_posix_generic ();
+
+ printf ("\nContinuing POSIX extended tests.\n");
+
+ /* Grouping tests that differ from basic's. */
+
+ test_should_match = true;
+ MATCH_SELF ("a)");
+
+ /* Valid use of special characters. */
+ test_match ("\\(a", "(a");
+ test_match ("a\\+", "a+");
+ test_match ("a\\?", "a?");
+ test_match ("\\{a", "{a");
+ test_match ("\\|a", "|a");
+ test_match ("a\\|b", "a|b");
+ test_match ("a\\|?", "a");
+ test_match ("a\\|?", "a|");
+ test_match ("a\\|*", "a");
+ test_match ("a\\|*", "a||");
+ test_match ("\\(*\\)", ")");
+ test_match ("\\(*\\)", "(()");
+ test_match ("a\\|+", "a|");
+ test_match ("a\\|+", "a||");
+ test_match ("\\(+\\)", "()");
+ test_match ("\\(+\\)", "(()");
+ test_match ("a\\||b", "a|");
+ test_match ("\\(?\\)", ")");
+ test_match ("\\(?\\)", "()");
+
+ test_match ("a+", "a");
+ test_match ("a+", "aa");
+ test_match ("a?", "");
+ test_match ("a?", "a");
+
+ /* Bracket expressions. */
+ test_match ("[(]", "(");
+ test_match ("[+]", "+");
+ test_match ("[?]", "?");
+ test_match ("[{]", "{");
+ test_match ("[|]", "|");
+ /* Subexpressions. */
+ test_match ("(a+)*", "");
+ test_match ("(a+)*", "aa");
+ test_match ("(a?)*", "");
+ test_match ("(a?)*", "aa");
+ /* (No) back references. */
+ test_match ("(a)\\1", "a1");
+ /* Invalid as intervals,
+ but are valid patterns. */
+ MATCH_SELF ("{");
+ test_match ("^{", "{");
+ test_match ("a|{", "{");
+ test_match ("({)", "{");
+ MATCH_SELF ("a{");
+ MATCH_SELF ("a{}");
+ MATCH_SELF ("a{-1");
+ MATCH_SELF ("a{-1}");
+ MATCH_SELF ("a{0");
+ MATCH_SELF ("a{0,");
+ MATCH_SELF (concat ("a{", dup_max_plus_one));
+ MATCH_SELF (concat (concat ("a{", dup_max_plus_one), ","));
+ MATCH_SELF ("a{1,0");
+ MATCH_SELF ("a{1,0}");
+ MATCH_SELF ("a{0,1");
+ test_match ("[a{0,1}]", "}");
+ test_match ("a{1,3}{-1}", "aaa{-1}");
+ test_match (concat ("a{1,3}{", dup_max_plus_one),
+ concat ("aaa{", dup_max_plus_one));
+ test_match ("a{1,3}{2,1}", "aaa{2,1}");
+ test_match ("a{1,3}{1,2", "aaa{1,2");
+ /* Valid consecutive repetitions. */
+ test_match ("a*+", "a");
+ test_match ("a*?", "a");
+ test_match ("a++", "a");
+ test_match ("a+*", "a");
+ test_match ("a+?", "a");
+ test_match ("a??", "a");
+ test_match ("a?*", "a");
+ test_match ("a?+", "a");
+
+ test_match ("a{2}?", "");
+ test_match ("a{2}?", "aa");
+ test_match ("a{2}+", "aa");
+ test_match ("a{2}{2}", "aaaa");
+
+ test_match ("a{1}?*", "");
+ test_match ("a{1}?*", "aa");
+
+ test_match ("(a?){0,3}b", "aaab");
+ test_fastmap ("(a?){0,3}b", "ab", 0, 0);
+ test_match ("(a+){0,3}b", "b");
+ test_fastmap ("(a+){0,3}b", "ab", 0, 0);
+ test_match ("(a+){0,3}b", "ab");
+ test_fastmap ("(a+){0,3}b", "ab", 0, 0);
+ test_match ("(a+){1,3}b", "aaab");
+ test_match ("(a?){1,3}b", "aaab");
+
+ test_match ("\\\\{1}", "\\"); /* Extended only. */
+
+ test_match ("(a?)?", "a");
+ test_match ("(a?b)?c", "abc");
+ test_match ("(a+)*b", "b");
+ /* Alternatives. */
+ test_match ("a|b", "a");
+ test_match ("a|b", "b");
+ test_fastmap ("a|b", "ab", 0, 0);
+
+ TEST_SEARCH ("a|b", "cb", 0, 2);
+ TEST_SEARCH ("a|b", "cb", 0, 2);
+
+ test_match ("(a|b|c)", "a");
+ test_match ("(a|b|c)", "b");
+ test_match ("(a|b|c)", "c");
+
+ test_match ("(a|b|c)*", "abccba");
+
+ test_match ("(a(b*))|c", "a"); /* xx do registers. */
+ test_match ("(a(b*))|c", "ab");
+ test_match ("(a(b*))|c", "c");
+
+ test_fastmap ("(a+?*|b)", "ab", 0, 0);
+ test_match ("(a+?*|b)", "b");
+ TEST_REGISTERS ("(a+?*|b)", "b", 0, 1, 0, 1, -1, -1);
+
+ test_fastmap ("(a+?*|b)*", "ab", 0, 0);
+ test_match ("(a+?*|b)*", "bb");
+ TEST_REGISTERS ("(a+?*|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("(a*|b)*", "ab", 0, 0);
+ test_match ("(a*|b)*", "bb");
+ TEST_REGISTERS ("(a*|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("((a*)|b)*", "ab", 0, 0);
+ test_match ("((a*)|b)*", "bb");
+ TEST_REGISTERS ("((a*)|b)*", "bb", 0, 2, 1, 2, 1, 1);
+
+ test_fastmap ("(a{0,}|b)*", "ab", 0, 0);
+ test_match ("(a{0,}|b)*", "bb");
+ TEST_REGISTERS ("(a{0,}|b)*", "bb", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap ("((a{0,})|b)*", "ab", 0, 0);
+ test_match ("((a{0,})|b)*", "bb");
+ TEST_REGISTERS ("((a{0,})|b)*", "bb", 0, 2, 1, 2, 1, 1);
+
+ /* With c's */
+ test_fastmap ("(a+?*|b)c", "abc", 0, 0);
+ test_match ("(a+?*|b)c", "bc");
+ TEST_REGISTERS ("(a+?*|b)c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_fastmap ("(a+?*|b)*c", "abc", 0, 0);
+ test_match ("(a+?*|b)*c", "bbc");
+ TEST_REGISTERS ("(a+?*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("(a*|b)*c", "abc", 0, 0);
+ test_match ("(a*|b)*c", "bbc");
+ TEST_REGISTERS ("(a*|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("((a*)|b)*c", "abc", 0, 0);
+ test_match ("((a*)|b)*c", "bbc");
+ TEST_REGISTERS ("((a*)|b)*c", "bbc", 0, 3, 1, 2, 1, 1);
+
+ test_fastmap ("(a{0,}|b)*c", "abc", 0, 0);
+ test_match ("(a{0,}|b)*c", "bbc");
+ TEST_REGISTERS ("(a{0,}|b)*c", "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap ("((a{0,})|b)*c", "abc", 0, 0);
+ test_match ("((a{0,})|b)*c", "bbc");
+ TEST_REGISTERS ("((a{0,})|b)*c", "bbc", 0, 3, 1, 2, 1, 1);
+
+
+ test_fastmap ("((a{0,}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a{0,}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a{0,}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a{0,}\\b\\<)|b)*", "b");
+ TEST_REGISTERS ("((a{0,}\\b\\<)|b)*", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,1}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,1}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,1}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,2}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,2}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,2}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+
+ test_fastmap ("((a+?*{0,4095}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,4095}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,4095}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,5119}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,5119}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,5119}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,6143}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,6143}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,6143}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,8191}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,8191}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,8191}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,16383}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,16383}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,16383}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)", "b");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)*", "b");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "b",
+ 0, 1, 0, 1, 0, 0);
+
+ test_fastmap ("((a+?*{0,}\\b\\<)|b)*", "ab", 0, 0);
+ test_match ("((a+?*{0,}\\b\\<)|b)*", "bb");
+ TEST_REGISTERS ("((a+?*{0,}\\b\\<)|b)*", "bb",
+ 0, 2, 1, 2, 0, 0);
+
+
+ /* `*' after group. */
+ test_match ("(a*|b*)*c", "c");
+ TEST_REGISTERS ("(a*|b*)*c", "c", 0, 1, 0, 0, -1, -1);
+
+ test_match ("(a*|b*)*c", "ac");
+ TEST_REGISTERS ("(a*|b*)*c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)*c", "aac");
+ TEST_REGISTERS ("(a*|b*)*c", "aac", 0, 3, 0, 2, -1, -1);
+
+ test_match ("(a*|b*)*c", "bbc");
+ TEST_REGISTERS ("(a*|b*)*c", "bbc", 0, 3, 0, 2, -1, -1);
+
+ test_match ("(a*|b*)*c", "abc");
+ TEST_REGISTERS ("(a*|b*)*c", "abc", 0, 3, 1, 2, -1, -1);
+
+ /* No `*' after group. */
+ test_match ("(a*|b*)c", "c");
+ TEST_REGISTERS ("(a*|b*)c", "c", 0, 1, 0, 0, -1, -1);
+
+ test_match ("(a*|b*)c", "ac");
+ TEST_REGISTERS ("(a*|b*)c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)c", "bc");
+ TEST_REGISTERS ("(a*|b*)c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a*|b*)c", "aac");
+ TEST_REGISTERS ("(a*|b*)c", "aac", 0, 3, 0, 2, -1, -1);
+
+ /* Same as above, but with no `*'s in alternatives.
+
+ test_match ("(a|b)*c", "c"); /* `*' after group. */
+ TEST_REGISTERS ("(a|b)*c", "c", 0, 1, -1, -1, -1, -1);
+
+ test_match ("(a|b)*c", "ac");
+ TEST_REGISTERS ("(a|b)*c", "ac", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a|b)*c", "bc");
+ TEST_REGISTERS ("(a|b)*c", "bc", 0, 2, 0, 1, -1, -1);
+
+ test_match ("(a|b)*c", "abc");
+ TEST_REGISTERS ("(a|b)*c", "abc", 0, 3, 1, 2, -1, -1);
+
+
+ test_match ("(a*|b*)c", "bbc");
+ TEST_REGISTERS ("(a*|b*)c", "bbc", 0, 3, 0, 2, -1, -1);
+
+ /* Complicated second alternative. */
+
+ test_match ("(a*|(b*)*)*c", "bc");
+ TEST_REGISTERS ("(a*|(b*)*)*c", "bc", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "bd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bd", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "bbd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "bbd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|(b*|c*)*)*d", "cd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "cd", 0, 2, 0, 1, 0, 1);
+
+ test_match ("(a*|(b*|c*)*)*d", "ccd");
+ TEST_REGISTERS ("(a*|(b*|c*)*)*d", "ccd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "aad");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "aad", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "bbd");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "bbd", 0, 3, 0, 2, 0, 2);
+
+ test_match ("(a*|b*|c*)*d", "ccd");
+ TEST_REGISTERS ("(a*|b*|c*)*d", "ccd", 0, 3, 0, 2, 0, 2);
+
+ /* Valid anchoring. */
+ valid_pattern ("a^");
+ valid_pattern ("a^b");
+ valid_pattern ("$a");
+ valid_pattern ("a$b");
+ valid_pattern ("foo^bar");
+ valid_pattern ("foo$bar");
+ valid_pattern ("(^)");
+ valid_pattern ("($)");
+ valid_pattern ("(^$)");
+
+ /* These are the same (but valid) as those (invalid) in other_test.c. */
+ valid_pattern
+ ("(((((((((((((((((((((((((((((((((a^)))))))))))))))))))))))))))))))))");
+ valid_pattern
+ ("((((((((((((((((((((((((((((((((($a)))))))))))))))))))))))))))))))))");
+ valid_pattern ("\\(^a\\)");
+ valid_pattern ("a\\|^b");
+ valid_pattern ("\\w^a");
+ valid_pattern ("\\W^a");
+ valid_pattern ("(a^)");
+ valid_pattern ("($a)");
+ valid_pattern ("a(^b)");
+ valid_pattern ("a$(b)");
+ valid_pattern ("(a)^b");
+ valid_pattern ("(a)$b");
+ valid_pattern ("(a)(^b)");
+ valid_pattern ("(a$)(b)");
+ valid_pattern ("(a|b)^c");
+ valid_pattern ("(a|b)$c");
+ valid_pattern ("(a$|b)c");
+ valid_pattern ("(a|b$)c");
+ valid_pattern ("a(b|^c)");
+ valid_pattern ("a(^b|c)");
+ valid_pattern ("a$(b|c)");
+ valid_pattern ("(a)(^b|c)");
+ valid_pattern ("(a)(b|^c)");
+ valid_pattern ("(b$|c)(a)");
+ valid_pattern ("(b|c$)(a)");
+ valid_pattern ("(a(^b|c))");
+ valid_pattern ("(a(b|^c))");
+ valid_pattern ("((b$|c)a)");
+ valid_pattern ("((b|c$)a)");
+ valid_pattern ("((^a|^b)^c)");
+ valid_pattern ("(c$(a$|b$))");
+ valid_pattern ("((^a|^b)^c)");
+ valid_pattern ("((a$|b$)c)");
+ valid_pattern ("(c$(a$|b$))");
+ valid_pattern ("((^a|^b)|^c)^d");
+ valid_pattern ("((a$|b$)|c$)d$");
+ valid_pattern ("d$(c$|(a$|b$))");
+ valid_pattern ("((^a|^b)|^c)(^d)");
+ valid_pattern ("((a$|b$)|c$)(d$)");
+ valid_pattern ("(d$)((a$|b$)|c$)");
+ valid_pattern ("((^a|^b)|^c)((^d))");
+ valid_pattern ("((a$|b$)|c$)((d$))");
+ valid_pattern ("((d$))((a$|b$)|c$)");
+ valid_pattern ("(((^a|^b))c|^d)^e");
+ valid_pattern ("(((a$|b$))c|d$)$e$");
+ valid_pattern ("e$(d$|c((a$|b$)))");
+ valid_pattern ("(^a)((^b))");
+ valid_pattern ("(a$)((b$))");
+ valid_pattern ("((^a))(^b)");
+ valid_pattern ("((a$))(b$)");
+ valid_pattern ("((^a))((^b))");
+ valid_pattern ("((a$))((b$))");
+ valid_pattern ("((^a)^b)");
+ valid_pattern ("((a$)b$)");
+ valid_pattern ("(b$(a$))");
+ valid_pattern ("(((^a)b)^c)");
+ valid_pattern ("(((a$)b)c$)");
+ valid_pattern ("(c$(b(a$)))");
+ valid_pattern ("(((^a)b)c)^d");
+ valid_pattern ("(((a$)b)c)d$");
+ valid_pattern ("d$(c(b(a$)))");
+ valid_pattern (".^a");
+ valid_pattern ("a$.");
+ valid_pattern ("[a]^b");
+ valid_pattern ("b$[a]");
+ valid_pattern ("\\(a$\\)");
+ valid_pattern ("a$\\|b");
+ valid_pattern ("(^a|^b)^c");
+ valid_pattern ("c$(a$|b$)");
+ valid_pattern ("(^a|^b)^|^c");
+ valid_pattern ("(a$|b$)$|$c$");
+ valid_pattern ("(a$|$b$)$|c$");
+ valid_pattern ("($a$|b$)$|c$");
+ valid_pattern ("$(a$|b$)$|c$");
+ valid_pattern ("^c|d(^a|^b)");
+ valid_pattern ("(^a|^b)|d^c");
+ valid_pattern ("c$|(a$|b$)d");
+ valid_pattern ("c$d|(a$|b$)");
+ valid_pattern ("c(^a|^b)|^d");
+ valid_pattern ("(a$|b$)c|d$");
+ valid_pattern ("c(((^a|^b))|^d)e");
+ valid_pattern ("(c((^a|^b))|^d)e");
+ valid_pattern ("((c(^a|^b))|^d)e");
+ valid_pattern ("(((^a|^b))|c^d)e");
+ valid_pattern ("(((^a|^b))|^d)^e");
+ valid_pattern ("(c$((a|b))|d)e$");
+ valid_pattern ("(c((a$|b$))|d)e$");
+ valid_pattern ("(c((a|b)$)|d)e$");
+ valid_pattern ("(c((a|b))|d$)e$");
+ valid_pattern ("^d(^c|e((a|b)))");
+ valid_pattern ("^d(c|^e((a|b)))");
+ valid_pattern ("^d(c|e(^(a|b)))");
+ valid_pattern ("^d(c|e((^a|b)))");
+ valid_pattern ("^d(c|e((a|^b)))");
+ valid_pattern ("^d(c|e((a|b^)))");
+ valid_pattern ("^d(c|e((a|b)^))");
+ valid_pattern ("^d(c|e((a|b))^)");
+ valid_pattern ("^d(c|e((a|b)))^");
+ valid_pattern ("d$(c$|e((a$|b$)))");
+ valid_pattern ("d(c$|e$((a$|b$)))");
+ valid_pattern ("(((^a|^b))^c)|^de");
+ valid_pattern ("(((^a|^b))c)|^d^e");
+ valid_pattern ("(((a$|b))c$)|de$");
+ valid_pattern ("(((a|b$))c$)|de$");
+ valid_pattern ("(((a|b))c$)|d$e$");
+ valid_pattern ("^d^e|^(c((a|b)))");
+ valid_pattern ("^de|^(c^((a|b)))");
+ valid_pattern ("^de|^(c(^(a|b)))");
+ valid_pattern ("^de|^(c((^a|b)))");
+ valid_pattern ("^de|^(c((a|^b)))");
+ valid_pattern ("^de|(^c(^(a|b)))");
+ valid_pattern ("^de|(^c((^a|b)))");
+ valid_pattern ("^de|(^c((a|^b)))");
+ valid_pattern ("de$|(c($(a|b)$))");
+ valid_pattern ("de$|(c$((a|b)$))");
+ valid_pattern ("de$|($c((a|b)$))");
+ valid_pattern ("de$|$(c((a|b)$))");
+ valid_pattern ("de$|(c($(a|b))$)");
+ valid_pattern ("de$|(c$((a|b))$)");
+ valid_pattern ("de$|$(c((a|b))$)");
+ valid_pattern ("de$|(c($(a|b)))$");
+ valid_pattern ("de$|(c$((a|b)))$");
+ valid_pattern ("de$|($c((a|b)))$");
+ valid_pattern ("de$|$(c((a|b)))$");
+ valid_pattern ("^a(^b|c)|^d");
+ valid_pattern ("^a(b|^c)|^d");
+ valid_pattern ("^a(b|c^)|^d");
+ valid_pattern ("^a(b|c)^|^d");
+ valid_pattern ("a$(b$|c$)|d$");
+ valid_pattern ("^d|^a(^b|c)");
+ valid_pattern ("^d|^a(b|^c)");
+ valid_pattern ("d$|a$(b$|c$)");
+ valid_pattern ("^d|^(b|c)^a");
+ valid_pattern ("d$|(b|c$)a$");
+ valid_pattern ("d$|(b$|c)a$");
+ valid_pattern ("^(a)^(b|c)|^d");
+ valid_pattern ("^(a)(^b|c)|^d");
+ valid_pattern ("^(a)(b|^c)|^d");
+ valid_pattern ("(a)$(b|c)$|d$");
+ valid_pattern ("(a$)(b|c)$|d$");
+ valid_pattern ("(^a)(^b|c)|^d");
+ valid_pattern ("(^a)(b|^c)|^d");
+ valid_pattern ("(a)$(b$|c$)|d$");
+ valid_pattern ("(a$)(b$|c$)|d$");
+ valid_pattern ("^d|^(b|c)^(a)");
+ valid_pattern ("^d|^(b|c)(^a)");
+ valid_pattern ("d$|(b|c$)(a)$");
+ valid_pattern ("d$|(b$|c)(a)$");
+ valid_pattern ("^d|(^b|^c)^(a)");
+ valid_pattern ("^d|(^b|^c)(^a)");
+ valid_pattern ("d$|(b|c)$(a$)");
+ valid_pattern ("d$|(b|c$)(a$)");
+ valid_pattern ("d$|(b$|c)(a$)");
+ valid_pattern ("^d|^(a)^(b|c)");
+ valid_pattern ("^d|^(a)(^b|c)");
+ valid_pattern ("^d|^(a)(b|^c)");
+ valid_pattern ("^d|(^a)^(b|c)");
+ valid_pattern ("^d|(^a)(^b|c)");
+ valid_pattern ("^d|(^a)(b|^c)");
+ valid_pattern ("d$|(a)$(b$|c$)");
+ valid_pattern ("d$|(a$)(b$|c$)");
+ valid_pattern ("((e^a|^b)|^c)|^d");
+ valid_pattern ("((^a|e^b)|^c)|^d");
+ valid_pattern ("((^a|^b)|e^c)|^d");
+ valid_pattern ("((^a|^b)|^c)|e^d");
+ valid_pattern ("d$e|(c$|(a$|b$))");
+ valid_pattern ("d$|(c$e|(a$|b$))");
+ valid_pattern ("d$|(c$|(a$e|b$))");
+ valid_pattern ("d$|(c$|(a$|b$e))");
+ valid_pattern ("d$|(c$|(a$|b$)e)");
+ valid_pattern ("d$|(c$|(a$|b$))e");
+ valid_pattern ("(a|b)^|c");
+ valid_pattern ("(a|b)|c^");
+ valid_pattern ("$(a|b)|c");
+ valid_pattern ("(a|b)|$c");
+ valid_pattern ("(a^|^b)|^c");
+ valid_pattern ("(^a|b^)|^c");
+ valid_pattern ("(^a|^b)|c^");
+ valid_pattern ("($a|b$)|c$");
+ valid_pattern ("(a$|$b)|c$");
+ valid_pattern ("(a$|b$)|$c");
+ valid_pattern ("c^|(^a|^b)");
+ valid_pattern ("^c|(a^|^b)");
+ valid_pattern ("^c|(^a|b^)");
+ valid_pattern ("$c|(a$|b$)");
+ valid_pattern ("c$|($a|b$)");
+ valid_pattern ("c$|(a$|$b)");
+ valid_pattern ("c^|^(a|b)");
+ valid_pattern ("^c|(a|b)^");
+ valid_pattern ("$c|(a|b)$");
+ valid_pattern ("c$|$(a|b)");
+ valid_pattern ("(a^|^b)c|^d");
+ valid_pattern ("(^a|b^)c|^d");
+ valid_pattern ("(^a|^b)c|d^");
+ valid_pattern ("(^a|^b)^c|^d");
+ valid_pattern ("(a|b)c$|$d");
+ valid_pattern ("(a|b)$c$|d$");
+ valid_pattern ("(a|b)$c$|d$");
+ valid_pattern ("(a|b$)c$|d$");
+ valid_pattern ("(a$|b)c$|d$");
+ valid_pattern ("($a|b)c$|d$");
+ valid_pattern ("$(a|b)c$|d$");
+ valid_pattern ("^d|^c^(a|b)");
+ valid_pattern ("^d|^c(^a|b)");
+ valid_pattern ("^d|^c(a|^b)");
+ valid_pattern ("^d|^c(a|b^)");
+ valid_pattern ("^d|^c(a|b)^");
+ valid_pattern ("$d|c(a$|b$)");
+ valid_pattern ("d$|c($a$|b$)");
+ valid_pattern ("d$|c$(a$|b$)");
+ valid_pattern ("d$|$c(a$|b$)");
+
+ valid_pattern ("(((a^|^b))c|^d)e");
+ valid_pattern ("(((^a|b^))c|^d)e");
+ valid_pattern ("(((^a|^b))^c|^d)e");
+ valid_pattern ("((^(a|b))c|d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a^|b))c|^d)e");
+ valid_pattern ("(^((a|b^))c|^d)e");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a|b))^c|^d)e");
+ valid_pattern ("(^((a|b))c^|^d)e");
+ valid_pattern ("(^((a|b))c|^d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+ valid_pattern ("(((a|b))c|d)$e$");
+ valid_pattern ("(((a|b))c|d$)e$");
+ valid_pattern ("(((a|b))c|$d)e$");
+ valid_pattern ("(((a|b))c$|d)e$");
+ valid_pattern ("(((a|b))$c|d)e$");
+ valid_pattern ("(((a|b)$)c|d)e$");
+ valid_pattern ("(((a|b$))c|d)e$");
+ valid_pattern ("(((a$|b))c|d)e$");
+ valid_pattern ("((($a|b))c|d)e$");
+ valid_pattern ("(($(a|b))c|d)e$");
+ valid_pattern ("($((a|b))c|d)e$");
+ valid_pattern ("$(((a|b))c|d)e$");
+ valid_pattern ("(^((a|b)^)c|^d)e");
+ valid_pattern ("(^((a|b))^c|^d)e");
+ valid_pattern ("(^((a|b))c|^d^)e");
+ valid_pattern ("(^((a|b))c|^d)^e");
+
+ valid_pattern ("^e(^d|c((a|b)))");
+ valid_pattern ("^e(d|^c((a|b)))");
+ valid_pattern ("^e(d|c^((a|b)))");
+ valid_pattern ("^e(d|c(^(a|b)))");
+ valid_pattern ("^e(d|c((^a|b)))");
+ valid_pattern ("^e(d|c((a|^b)))");
+ valid_pattern ("^e(d|c((a|b^)))");
+ valid_pattern ("^e(d|c((a|b)^))");
+ valid_pattern ("^e(d|c((a|b))^)");
+ valid_pattern ("^e(d|c((a|b)))^");
+ valid_pattern ("e$(d$|c((a$|b$)))");
+ valid_pattern ("e(d$|c$((a$|b$)))");
+ valid_pattern ("e(d$|c($(a$|b$)))");
+ valid_pattern ("e(d$|c(($a$|b$)))");
+ valid_pattern ("e$(d$|c((a|b)$))");
+ valid_pattern ("e($d$|c((a|b)$))");
+ valid_pattern ("e(d$|$c((a|b)$))");
+ valid_pattern ("e(d$|c$((a|b)$))");
+ valid_pattern ("e(d$|c($(a|b)$))");
+ valid_pattern ("e(d$|c(($a|b)$))");
+ valid_pattern ("e(d$|c((a|$b)$))");
+ valid_pattern ("e(d$|c((a$|$b$)))");
+
+ valid_pattern ("e$(d$|c((a|b))$)");
+ valid_pattern ("e($d$|c((a|b))$)");
+ valid_pattern ("e(d$|$c((a|b))$)");
+ valid_pattern ("e(d$|c$((a|b))$)");
+ valid_pattern ("e(d$|c($(a|b))$)");
+ valid_pattern ("e(d$|c(($a|b))$)");
+ valid_pattern ("e(d$|c((a|$b))$)");
+ valid_pattern ("e$(d$|c((a|b)))$");
+ valid_pattern ("e($d$|c((a|b)))$");
+ valid_pattern ("e(d$|$c((a|b)))$");
+ valid_pattern ("e(d$|c$((a|b)))$");
+ valid_pattern ("e(d$|c($(a|b)))$");
+ valid_pattern ("e(d$|c(($a|b)))$");
+ valid_pattern ("e(d$|c((a|$b)))$");
+ valid_pattern ("(((^a|^b)^)c)|^de");
+ valid_pattern ("(((^a|^b))^c)|^de");
+ valid_pattern ("(((^a|^b))c)^|^de");
+ valid_pattern ("$(((a|b))c$)|de$");
+ valid_pattern ("($((a|b))c$)|de$");
+ valid_pattern ("(($(a|b))c$)|de$");
+ valid_pattern ("((($a|b))c$)|de$");
+ valid_pattern ("(((a|$b))c$)|de$");
+ valid_pattern ("(((a|b)$)c$)|de$");
+ valid_pattern ("(((a|b))$c$)|de$");
+ valid_pattern ("$(((a|b))c)$|de$");
+ valid_pattern ("($((a|b))c)$|de$");
+ valid_pattern ("(($(a|b))c)$|de$");
+ valid_pattern ("((($a|b))c)$|de$");
+ valid_pattern ("(((a|$b))c)$|de$");
+ valid_pattern ("(((a|b)$)c)$|de$");
+ valid_pattern ("(((a|b))$c)$|de$");
+ valid_pattern ("^ed|^(c((a|b)))^");
+ valid_pattern ("^ed|^(c((a|b))^)");
+ valid_pattern ("^ed|^(c((a|b)^))");
+ valid_pattern ("^ed|^(c((a|b^)))");
+ valid_pattern ("^ed|^(c((a^|b)))");
+ valid_pattern ("^ed|^(c((^a|b)))");
+ valid_pattern ("^ed|^(c(^(a|b)))");
+ valid_pattern ("^ed|^(c^((a|b)))");
+ valid_pattern ("^ed|(^c((a|b)))^");
+ valid_pattern ("^ed|(^c((a|b))^)");
+ valid_pattern ("^ed|(^c((a|b)^))");
+ valid_pattern ("^ed|(^c((a|b^)))");
+ valid_pattern ("^ed|(^c((a|^b)))");
+ valid_pattern ("^ed|(^c((a^|b)))");
+ valid_pattern ("^ed|(^c((^a|b)))");
+ valid_pattern ("^ed|(^c(^(a|b)))");
+ valid_pattern ("^ed|(^c(^(a|b)))");
+ valid_pattern ("^ed|(^c^((a|b)))");
+ valid_pattern ("ed$|$(c((a|b)))$");
+ valid_pattern ("ed$|($c((a|b)))$");
+ valid_pattern ("ed$|(c$((a|b)))$");
+ valid_pattern ("ed$|(c($(a|b)))$");
+ valid_pattern ("ed$|(c(($a|b)))$");
+ valid_pattern ("ed$|(c((a|$b)))$");
+ valid_pattern ("ed$|$(c((a|b))$)");
+ valid_pattern ("ed$|($c((a|b))$)");
+ valid_pattern ("ed$|(c$((a|b))$)");
+ valid_pattern ("ed$|(c($(a|b))$)");
+ valid_pattern ("ed$|(c(($a|b))$)");
+ valid_pattern ("ed$|(c((a|$b))$)");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a|b)$))");
+ valid_pattern ("ed$|($c((a|b)$))");
+ valid_pattern ("ed$|(c$((a|b)$))");
+ valid_pattern ("ed$|(c($(a|b)$))");
+ valid_pattern ("ed$|(c(($a|b)$))");
+ valid_pattern ("ed$|(c((a|$b)$))");
+ valid_pattern ("ed$|$(c((a$|b$)))");
+ valid_pattern ("ed$|($c((a$|b$)))");
+ valid_pattern ("ed$|(c$((a$|b$)))");
+ valid_pattern ("ed$|(c($(a$|b$)))");
+ valid_pattern ("ed$|(c(($a$|b$)))");
+ valid_pattern ("ed$|(c((a$|$b$)))");
+ valid_pattern ("^a(b|c)^|^d");
+ valid_pattern ("^a(b|c^)|^d");
+ valid_pattern ("^a(b|^c)|^d");
+ valid_pattern ("^a(b^|c)|^d");
+ valid_pattern ("^a(^b|c)|^d");
+ valid_pattern ("^a^(b|c)|^d");
+ valid_pattern ("$a(b$|c$)|d$");
+ valid_pattern ("a$(b$|c$)|d$");
+ valid_pattern ("a($b$|c$)|d$");
+ valid_pattern ("a(b$|$c$)|d$");
+ valid_pattern ("a(b$|c$)|$d$");
+ valid_pattern ("^(a^)(b|c)|^d");
+ valid_pattern ("^(a)^(b|c)|^d");
+ valid_pattern ("^(a)(^b|c)|^d");
+ valid_pattern ("^(a)(b^|c)|^d");
+ valid_pattern ("^(a)(b|^c)|^d");
+ valid_pattern ("^(a)(b|c^)|^d");
+ valid_pattern ("^(a)(b|c)^|^d");
+ valid_pattern ("(^a^)(b|c)|^d");
+ valid_pattern ("(^a)^(b|c)|^d");
+ valid_pattern ("(^a)(^b|c)|^d");
+ valid_pattern ("(^a)(b^|c)|^d");
+ valid_pattern ("(^a)(b|^c)|^d");
+ valid_pattern ("(^a)(b|c^)|^d");
+ valid_pattern ("(^a)(b|c)^|^d");
+
+ valid_pattern ("(a)(b$|c$)d$");
+ valid_pattern ("(a)(b|$c)$|d$");
+ valid_pattern ("(a)($b|c)$|d$");
+ valid_pattern ("(a)$(b|c)$|d$");
+ valid_pattern ("(a$)(b|c)$|d$");
+ valid_pattern ("($a)(b|c)$|d$");
+ valid_pattern ("$(a)(b|c)$|d$");
+ valid_pattern ("(b|c)($a)$|d$");
+ valid_pattern ("(b|c)$(a)$|d$");
+ valid_pattern ("(b|c$)(a)$|d$");
+ valid_pattern ("(b|$c)(a)$|d$");
+ valid_pattern ("(b$|c)(a)$|d$");
+ valid_pattern ("($b|c)(a)$|d$");
+ valid_pattern ("$(b|c)(a)$|d$");
+ valid_pattern ("(b|c)($a$)|d$");
+ valid_pattern ("(b|c)$(a$)|d$");
+ valid_pattern ("(b|c$)(a$)|d$");
+ valid_pattern ("(b|$c)(a$)|d$");
+ valid_pattern ("(b$|c)(a$)|d$");
+ valid_pattern ("($b|c)(a$)|d$");
+ valid_pattern ("$(b|c)(a$)|d$");
+ valid_pattern ("(a)$(b$|c$)|d$");
+ valid_pattern ("(a$)(b$|c$)|d$");
+ valid_pattern ("($a)(b$|c$)|d$");
+ valid_pattern ("$(a)(b$|c$)|d$");
+ valid_pattern ("^d|^(b^|c)(a)");
+ valid_pattern ("^d|^(b|c^)(a)");
+ valid_pattern ("^d|^(b|c)^(a)");
+ valid_pattern ("^d|^(b|c)(^a)");
+ valid_pattern ("^d|^(b|c)(a^)");
+ valid_pattern ("^d|^(b|c)(a)^");
+ valid_pattern ("^d|(^b|^c^)(a)");
+ valid_pattern ("^d|(^b|^c)^(a)");
+ valid_pattern ("^d|(^b|^c)(^a)");
+ valid_pattern ("^d|(^b|^c)(a^)");
+ valid_pattern ("^d|(^b|^c)(a)^");
+ valid_pattern ("d$|(b|c)($a$)");
+ valid_pattern ("d$|(b|c)$(a$)");
+ valid_pattern ("d$|(b|c$)(a$)");
+ valid_pattern ("d$|(b$|c)(a$)");
+ valid_pattern ("d$|($b|c)(a$)");
+ valid_pattern ("d$|$(b|c)(a$)");
+ valid_pattern ("d$|(b|c)($a)$");
+ valid_pattern ("d$|(b|c)$(a)$");
+ valid_pattern ("d$|(b|c$)(a)$");
+ valid_pattern ("d$|(b$|c)(a)$");
+ valid_pattern ("d$|($b|c)(a)$");
+ valid_pattern ("d$|$(b|c)(a)$");
+ valid_pattern ("^d|^(a^)(b|c)");
+ valid_pattern ("^d|^(a)^(b|c)");
+ valid_pattern ("^d|^(a)(^b|c)");
+ valid_pattern ("^d|^(a)(b^|c)");
+ valid_pattern ("^d|^(a)(b|^c)");
+ valid_pattern ("^d|^(a)(b|c^)");
+ valid_pattern ("^d|^(a)(b|c)^");
+ valid_pattern ("^d|(^a^)(b|c)");
+ valid_pattern ("^d|(^a)^(b|c)");
+ valid_pattern ("^d|(^a)(^b|c)");
+ valid_pattern ("^d|(^a)(b^|c)");
+ valid_pattern ("^d|(^a)(b|^c)");
+ valid_pattern ("^d|(^a)(b|c^)");
+ valid_pattern ("^d|(^a)(b|c)^");
+ valid_pattern ("d$|(a)$(b$|c$)");
+ valid_pattern ("d$|(a$)(b$|c$)");
+ valid_pattern ("d$|($a)(b$|c$)");
+ valid_pattern ("d$|$(a)(b$|c$)");
+ valid_pattern ("d$|(a)(b|$c)$");
+ valid_pattern ("d$|(a)($b|c)$");
+ valid_pattern ("d$|(a)$(b|c)$");
+ valid_pattern ("d$|(a$)(b|c)$");
+ valid_pattern ("d$|($a)(b|c)$");
+ valid_pattern ("d$|$(a)(b|c)$");
+ valid_pattern ("((^a|^b)|^c)|^d^");
+ valid_pattern ("((^a|^b)|^c)^|^d");
+ valid_pattern ("((^a|^b)|^c^)|^d");
+ valid_pattern ("((^a|^b)^|^c)|^d");
+ valid_pattern ("((^a|^b^)|^c)|^d");
+ valid_pattern ("((^a^|^b)|^c)|^d");
+ valid_pattern ("((a|b)|c)|$d$");
+ valid_pattern ("((a|b)|$c)|d$");
+ valid_pattern ("((a|$b)|c)|d$");
+ valid_pattern ("(($a|b)|c)|d$");
+ valid_pattern ("($(a|b)|c)|d$");
+ valid_pattern ("$((a|b)|c)|d$");
+ valid_pattern ("^d^|(c|(a|b))");
+ valid_pattern ("^d|(c^|(a|b))");
+ valid_pattern ("^d|(c|(a^|b))");
+ valid_pattern ("^d|(c|(a|b^))");
+ valid_pattern ("^d|(c|(a|b)^)");
+ valid_pattern ("^d|(c|(a|b))^");
+ valid_pattern ("d$|(c$|(a$|$b$))");
+ valid_pattern ("d$|(c$|($a$|b$))");
+ valid_pattern ("d$|($c$|(a$|b$))");
+ valid_pattern ("d$|$(c$|(a$|b$))");
+ valid_pattern ("$d$|(c$|(a$|b$))");
+ valid_pattern ("d$|(c$|(a|$b)$)");
+ valid_pattern ("d$|(c$|($a|b)$)");
+ valid_pattern ("d$|($c$|(a|b)$)");
+ valid_pattern ("d$|$(c$|(a|b)$)");
+ valid_pattern ("$d$|(c$|(a|b)$)");
+ valid_pattern ("d$|(c$|(a|$b))$");
+ valid_pattern ("d$|(c$|($a|b))$");
+ valid_pattern ("d$|($c$|(a|b))$");
+ valid_pattern ("d$|$(c$|(a|b))$");
+ valid_pattern ("$d$|(c$|(a|b))$");
+ valid_pattern ("^c^|(^a|^b)");
+ valid_pattern ("^c|(^a^|^b)");
+ valid_pattern ("^c|(^a|^b^)");
+ valid_pattern ("^c|(^a|^b)^");
+ valid_pattern ("c$|(a$|$b$)");
+ valid_pattern ("c$|($a$|b$)");
+ valid_pattern ("c$|$(a$|b$)");
+ valid_pattern ("$c$|(a$|b$)");
+ valid_pattern ("^d^(c|e((a|b)))");
+ valid_pattern ("^d(^c|e((a|b)))");
+ valid_pattern ("^d(c^|e((a|b)))");
+ valid_pattern ("^d(c|^e((a|b)))");
+ valid_pattern ("^d(c|e^((a|b)))");
+ valid_pattern ("^d(c|e(^(a|b)))");
+ valid_pattern ("^d(c|e((^a|b)))");
+ valid_pattern ("^d(c|e((a|^b)))");
+ valid_pattern ("^d(c|e((a|b^)))");
+ valid_pattern ("^d(c|e((a|b)^))");
+ valid_pattern ("^d(c|e((a|b))^)");
+ valid_pattern ("^d(c|e((a|b)))^");
+ valid_pattern ("d(c$|e($(a$|b$)))");
+ valid_pattern ("d(c$|e$((a$|b$)))");
+ valid_pattern ("d(c$|$e((a$|b$)))");
+ valid_pattern ("d($c$|e((a$|b$)))");
+ valid_pattern ("d$(c$|e((a$|b$)))");
+ valid_pattern ("$d(c$|e((a$|b$)))");
+ valid_pattern ("^d|^a^(b|c)");
+ valid_pattern ("^d|^a(^b|c)");
+ valid_pattern ("^d|^a(b^|c)");
+ valid_pattern ("^d|^a(b|^c)");
+ valid_pattern ("^d|^a(b|c^)");
+ valid_pattern ("^d|^a(b|c)^");
+ valid_pattern ("d$|a($b$|c$)");
+ valid_pattern ("d$|a$(b$|c$)");
+ valid_pattern ("d$|$a(b$|c$)");
+ valid_pattern ("$d$|a(b$|c$)");
+ valid_pattern ("^d|^(b^|c)a");
+ valid_pattern ("^d|^(b|c^)a");
+ valid_pattern ("^d|^(b|c)^a");
+ valid_pattern ("^d|^(b|c)a^");
+ valid_pattern ("d$|(b|c)$a$");
+ valid_pattern ("d$|(b|c$)a$");
+ valid_pattern ("d$|(b|$c)a$");
+ valid_pattern ("d$|(b$|c)a$");
+ valid_pattern ("d$|($b|c)a$");
+ valid_pattern ("d$|$(b|c)a$");
+ valid_pattern ("$d$|(b|c)a$");
+
+ /* xx Do these use all the valid_nonposix_pattern ones in other_test.c? */
+
+ TEST_SEARCH ("(^a|^b)c", "ac", 0, 2);
+ TEST_SEARCH ("(^a|^b)c", "bc", 0, 2);
+ TEST_SEARCH ("c(a$|b$)", "ca", 0, 2);
+ TEST_SEARCH ("c(a$|b$)", "cb", 0, 2);
+ TEST_SEARCH ("^(a|b)|^c", "ad", 0, 2);
+ TEST_SEARCH ("^(a|b)|^c", "bd", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "da", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "db", 0, 2);
+ TEST_SEARCH ("(a|b)$|c$", "dc", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "ad", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "bd", 0, 2);
+ TEST_SEARCH ("(^a|^b)|^c", "cd", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "da", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "db", 0, 2);
+ TEST_SEARCH ("(a$|b$)|c$", "dc", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "ad", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "bd", 0, 2);
+ TEST_SEARCH ("^c|(^a|^b)", "cd", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "da", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "db", 0, 2);
+ TEST_SEARCH ("c$|(a$|b$)", "dc", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "ad", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "bd", 0, 2);
+ TEST_SEARCH ("^c|^(a|b)", "cd", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "da", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "db", 0, 2);
+ TEST_SEARCH ("c$|(a|b)$", "dc", 0, 2);
+ TEST_SEARCH ("(^a|^b)c|^d", "ace", 0, 3);
+ TEST_SEARCH ("(^a|^b)c|^d", "bce", 0, 3);
+ TEST_SEARCH ("(^a|^b)c|^d", "de", 0, 2);
+ TEST_SEARCH ("(a|b)c$|d$", "eac", 0, 3);
+ TEST_SEARCH ("(a|b)c$|d$", "ebc", 0, 3);
+ TEST_SEARCH ("(a|b)c$|d$", "ed", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "cae", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "cbe", 0, 3);
+ TEST_SEARCH ("^d|^c(a|b)", "de", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "eca", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "ecb", 0, 3);
+ TEST_SEARCH ("d$|c(a$|b$)", "ed", 0, 3);
+
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("(((^a|^b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("((^(a|b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("((^(a|b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("((^(a|b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("(^((a|b))c|^d)e", "acef", 0, 4);
+ TEST_SEARCH ("(^((a|b))c|^d)e", "bcef", 0, 4);
+ TEST_SEARCH ("(^((a|b))c|^d)e", "def", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c|d)e$", "face", 0, 4);
+ TEST_SEARCH ("(((a|b))c|d)e$", "fbce", 0, 4);
+ TEST_SEARCH ("(((a|b))c|d)e$", "fde", 0, 3);
+
+ TEST_SEARCH ("^e(d|c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^e(d|c((a|b)))", "ecaf", 0, 4);
+ TEST_SEARCH ("^e(d|c((a|b)))", "ecbf", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "feca", 0, 4);
+ TEST_SEARCH ("e(d$|c((a$|b$)))", "fecb", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a|b)$))", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)$))", "feca", 0, 4);
+ TEST_SEARCH ("e(d$|c((a|b)$))", "fecb", 0, 4);
+
+ TEST_SEARCH ("e(d$|c((a|b))$)", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b))$)", "feca", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b))$)", "fecb", 0, 3);
+
+ TEST_SEARCH ("e(d$|c((a|b)))$", "fed", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)))$", "feca", 0, 3);
+ TEST_SEARCH ("e(d$|c((a|b)))$", "fecb", 0, 3);
+
+ TEST_SEARCH ("(((^a|^b))c)|^de", "acf", 0, 3);
+ TEST_SEARCH ("(((^a|^b))c)|^de", "bcf", 0, 3);
+ TEST_SEARCH ("(((^a|^b))c)|^de", "def", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c$)|de$", "fac", 0, 3);
+ TEST_SEARCH ("(((a|b))c$)|de$", "fbc", 0, 3);
+ TEST_SEARCH ("(((a|b))c$)|de$", "fde", 0, 3);
+
+ TEST_SEARCH ("(((a|b))c)$|de$", "fac", 0, 3);
+ TEST_SEARCH ("(((a|b))c)$|de$", "fbc", 0, 3);
+ TEST_SEARCH ("(((a|b))c)$|de$", "fde", 0, 3);
+
+ TEST_SEARCH ("^ed|^(c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^ed|^(c((a|b)))", "caf", 0, 3);
+ TEST_SEARCH ("^ed|^(c((a|b)))", "cbf", 0, 3);
+
+ TEST_SEARCH ("^ed|(^c((a|b)))", "edf", 0, 3);
+ TEST_SEARCH ("^ed|(^c((a|b)))", "caf", 0, 3);
+ TEST_SEARCH ("^ed|(^c((a|b)))", "cbf", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)))$", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b))$)", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a|b)$))", "fcb", 0, 3);
+
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fed", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fca", 0, 3);
+ TEST_SEARCH ("ed$|(c((a$|b$)))", "fcb", 0, 3);
+
+ TEST_SEARCH ("^a(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("^a(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("^a(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("a(b$|c$)|d$", "fab", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|d$", "fac", 0, 3);
+ TEST_SEARCH ("a(b$|c$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("^(a)(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("^(a)(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("^(a)(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("(^a)(b|c)|^d", "abe", 0, 3);
+ TEST_SEARCH ("(^a)(b|c)|^d", "ace", 0, 3);
+ TEST_SEARCH ("(^a)(b|c)|^d", "df", 0, 2);
+
+ TEST_SEARCH ("(a)(b|c)$|d$", "fab", 0, 3);
+ TEST_SEARCH ("(a)(b|c)$|d$", "fac", 0, 3);
+ TEST_SEARCH ("(a)(b|c)$|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(b|c)(a)$|d$", "fba", 0, 3);
+ TEST_SEARCH ("(b|c)(a)$|d$", "fca", 0, 3);
+ TEST_SEARCH ("(b|c)(a)$|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(b|c)(a$)|d$", "fba", 0, 3);
+ TEST_SEARCH ("(b|c)(a$)|d$", "fca", 0, 3);
+ TEST_SEARCH ("(b|c)(a$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fab", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fac", 0, 3);
+ TEST_SEARCH ("(a)(b$|c$)|d$", "fd", 0, 2);
+
+ TEST_SEARCH ("^d|^(b|c)(a)", "df", 0, 2);
+ TEST_SEARCH ("^d|^(b|c)(a)", "baf", 0, 3);
+ TEST_SEARCH ("^d|^(b|c)(a)", "caf", 0, 3);
+
+ TEST_SEARCH ("^d|(^b|^c)(a)", "df", 0, 2);
+ TEST_SEARCH ("^d|(^b|^c)(a)", "baf", 0, 3);
+ TEST_SEARCH ("^d|(^b|^c)(a)", "caf", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a)$", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a)$", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a)$", "fca", 0, 3);
+
+ TEST_SEARCH ("d$|(b|c)(a$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fba", 0, 3);
+ TEST_SEARCH ("d$|(b|c)(a$)", "fca", 0, 3);
+
+ TEST_SEARCH ("^d|^(a)(b|c)", "df", 0, 2);
+ TEST_SEARCH ("^d|^(a)(b|c)", "abf", 0, 3);
+ TEST_SEARCH ("^d|^(a)(b|c)", "acf", 0, 3);
+
+ TEST_SEARCH ("^d|(^a)(b|c)", "df", 0, 2);
+ TEST_SEARCH ("^d|(^a)(b|c)", "abf", 0, 3);
+ TEST_SEARCH ("^d|(^a)(b|c)", "acf", 0, 3);
+
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fab", 0, 3);
+ TEST_SEARCH ("d$|(a)(b$|c$)", "fac", 0, 3);
+
+ TEST_SEARCH ("d$|(a)(b|c)$", "fd", 0, 2);
+ TEST_SEARCH ("d$|(a)(b|c)$", "fab", 0, 3);
+ TEST_SEARCH ("d$|(a)(b|c)$", "fac", 0, 3);
+
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "ae", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "be", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "ce", 0, 2);
+ TEST_SEARCH ("((^a|^b)|^c)|^d", "de", 0, 2);
+
+ TEST_SEARCH ("((a|b)|c)|d$", "ed", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "ea", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "eb", 0, 2);
+ TEST_SEARCH ("((a|b)|c)|d$", "ec", 0, 2);
+
+ TEST_SEARCH ("^d|(c|(a|b))", "de", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a$|b$))", "eb", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b)$)", "eb", 0, 2);
+
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ed", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ec", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "ea", 0, 2);
+ TEST_SEARCH ("d$|(c$|(a|b))$", "eb", 0, 2);
+
+ test_match ("a|^b", "b");
+ test_match ("a|b$", "b");
+ test_match ("^b|a", "b");
+ test_match ("b$|a", "b");
+ test_match ("(^a)", "a");
+ test_match ("(a$)", "a");
+ TEST_SEARCH ("c|^ab", "aba", 0, 3);
+ TEST_SEARCH ("c|ba$", "aba", 0, 3);
+ TEST_SEARCH ("^ab|c", "aba", 0, 3);
+ TEST_SEARCH ("ba$|c", "aba", 0, 3);
+ TEST_SEARCH ("(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(a$)", "ba", 0, 2);
+
+ TEST_SEARCH ("(^a$)", "a", 0, 1);
+ TEST_SEARCH ("(^a)", "ab", 0, 2);
+ TEST_SEARCH ("(b$)", "ab", 0, 2);
+
+ /* Backtracking. */
+ /* Per POSIX D11.1 p. 108, leftmost longest match. */
+ test_match ("(wee|week)(knights|night)", "weeknights");
+
+ test_match ("(fooq|foo)qbar", "fooqbar");
+ test_match ("(fooq|foo)(qbarx|bar)", "fooqbarx");
+
+ /* Take first alternative that does the longest match. */
+ test_all_registers ("(fooq|(foo)|(fo))((qbarx)|(oqbarx)|bar)", "fooqbarx",
+ "", 0, 8, 0, 3, 0, 3, -1, -1, 3, 8, 3, 8, -1, -1, -1, -1, -1, -1,
+ -1, -1);
+
+ test_match ("(fooq|foo)*qbar", "fooqbar");
+ test_match ("(fooq|foo)*(qbar)", "fooqbar");
+ test_match ("(fooq|foo)*(qbar)*", "fooqbar");
+
+ test_match ("(fooq|fo|o)*qbar", "fooqbar");
+ test_match ("(fooq|fo|o)*(qbar)", "fooqbar");
+ test_match ("(fooq|fo|o)*(qbar)*", "fooqbar");
+
+ test_match ("(fooq|fo|o)*(qbar|q)*", "fooqbar");
+ test_match ("(fooq|foo)*(qbarx|bar)", "fooqbarx");
+ test_match ("(fooq|foo)*(qbarx|bar)*", "fooqbarx");
+
+ test_match ("(fooq|fo|o)+(qbar|q)+", "fooqbar");
+ test_match ("(fooq|foo)+(qbarx|bar)", "fooqbarx");
+ test_match ("(fooq|foo)+(qbarx|bar)+", "fooqbarx");
+
+ /* Per Mike Haertel. */
+ test_match ("(foo|foobarfoo)(bar)*", "foobarfoo");
+
+ /* Combination. */
+ test_match ("[ab]?c", "ac");
+ test_match ("[ab]*c", "ac");
+ test_match ("[ab]+c", "ac");
+ test_match ("(a|b)?c", "ac");
+ test_match ("(a|b)*c", "ac");
+ test_match ("(a|b)+c", "ac");
+ test_match ("(a*c)?b", "b");
+ test_match ("(a*c)+b", "aacb");
+ /* Registers. */
+ /* Per David A. Willcox. */
+ test_match ("a((b)|(c))d", "acd");
+ test_all_registers ("a((b)|(c))d", "acd", "", 0, 3, 1, 2, -1, -1, 1, 2,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+
+ /* Extended regular expressions, continued; these don't match their strings. */
+ test_should_match = false;
+
+#if 0
+ /* Invalid use of special characters. */
+ /* These are not invalid anymore, since POSIX says the behavior is
+ undefined, and we prefer context-independent to context-invalid. */
+ invalid_pattern (REG_BADRPT, "*");
+ invalid_pattern (REG_BADRPT, "a|*");
+ invalid_pattern (REG_BADRPT, "(*)");
+ invalid_pattern (REG_BADRPT, "^*");
+ invalid_pattern (REG_BADRPT, "+");
+ invalid_pattern (REG_BADRPT, "a|+");
+ invalid_pattern (REG_BADRPT, "(+)");
+ invalid_pattern (REG_BADRPT, "^+");
+
+ invalid_pattern (REG_BADRPT, "?");
+ invalid_pattern (REG_BADRPT, "a|?");
+ invalid_pattern (REG_BADRPT, "(?)");
+ invalid_pattern (REG_BADRPT, "^?");
+
+ invalid_pattern (REG_BADPAT, "|");
+ invalid_pattern (REG_BADPAT, "a|");
+ invalid_pattern (REG_BADPAT, "a||");
+ invalid_pattern (REG_BADPAT, "(|a)");
+ invalid_pattern (REG_BADPAT, "(a|)");
+
+ invalid_pattern (REG_BADPAT, PARENS_TO_OPS ("(|)"));
+
+ invalid_pattern (REG_BADRPT, "{1}");
+ invalid_pattern (REG_BADRPT, "a|{1}");
+ invalid_pattern (REG_BADRPT, "^{1}");
+ invalid_pattern (REG_BADRPT, "({1})");
+
+ invalid_pattern (REG_BADPAT, "|b");
+
+ invalid_pattern (REG_BADRPT, "^{0,}*");
+ invalid_pattern (REG_BADRPT, "$*");
+ invalid_pattern (REG_BADRPT, "${0,}*");
+#endif /* 0 */
+
+ invalid_pattern (REG_EESCAPE, "\\");
+
+ test_match ("a?b", "a");
+
+
+ test_match ("a+", "");
+ test_match ("a+b", "a");
+ test_match ("a?", "b");
+
+#if 0
+ /* We make empty groups valid now, since they are undefined in POSIX.
+ (13 Sep 92) */
+ /* Subexpressions. */
+ invalid_pattern (REG_BADPAT, "()");
+ invalid_pattern (REG_BADPAT, "a()");
+ invalid_pattern (REG_BADPAT, "()b");
+ invalid_pattern (REG_BADPAT, "a()b");
+ invalid_pattern (REG_BADPAT, "()*");
+ invalid_pattern (REG_BADPAT, "(()*");
+#endif
+ /* Invalid intervals. */
+ test_match ("a{2}*", "aaa");
+ test_match ("a{2}?", "aaa");
+ test_match ("a{2}+", "aaa");
+ test_match ("a{2}{2}", "aaa");
+ test_match ("a{1}{1}{2}", "aaa");
+ test_match ("a{1}{1}{2}", "a");
+ /* Invalid alternation. */
+ test_match ("a|b", "c");
+
+ TEST_SEARCH ("c|^ba", "aba", 0, 3);
+ TEST_SEARCH ("c|ab$", "aba", 0, 3);
+ TEST_SEARCH ("^ba|c", "aba", 0, 3);
+ TEST_SEARCH ("ab$|c", "aba", 0, 3);
+ /* Invalid anchoring. */
+ TEST_SEARCH ("(^a)", "ba", 0, 2);
+ TEST_SEARCH ("(b$)", "ba", 0, 2);
+
+ printf ("\nFinished POSIX extended tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-generic.c b/gnu/lib/libregex/test/psx-generic.c
new file mode 100644
index 0000000..8e97f75
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-generic.c
@@ -0,0 +1,336 @@
+/* psx-generic.c: test POSIX re's independent of us using basic or
+ extended syntax. */
+
+#include "test.h"
+
+
+void
+test_posix_generic ()
+{
+ int omit_generic_tests = 0; /* reset in debugger to skip */
+
+ if (omit_generic_tests)
+ return;
+ /* Tests somewhat in the order of P1003.2. */
+
+ /* Both posix basic and extended; should match. */
+
+ printf ("\nStarting generic POSIX tests.\n");
+ test_grouping ();
+ test_intervals ();
+
+ test_should_match = true;
+ /* Ordinary characters. */
+ printf ("\nContinuing generic POSIX tests.\n");
+
+ MATCH_SELF ("");
+ test_fastmap ("", "", 0, 0);
+ test_fastmap_search ("", "", "", 0, 0, 2, 0, 0);
+ TEST_REGISTERS ("", "", 0, 0, -1, -1, -1, -1);
+ TEST_SEARCH ("", "", 0, 0);
+ TEST_SEARCH_2 ("", "", "", 0, 1, 0);
+
+ MATCH_SELF ("abc");
+ test_fastmap ("abc", "a", 0, 0);
+ TEST_REGISTERS ("abc", "abc", 0, 3, -1, -1, -1, -1);
+ TEST_REGISTERS ("abc", "xabcx", 1, 4, -1, -1, -1, -1);
+
+ test_match ("\\a","a");
+ test_match ("\\0", "0");
+
+ TEST_SEARCH ("a", "ab", 0, 2);
+ TEST_SEARCH ("b", "ab", 0, 2);
+ TEST_SEARCH ("a", "ab", 1, -2);
+ TEST_SEARCH_2 ("a", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("b", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("a", "a", "b", 1, -2, 2);
+
+ test_match ("\n", "\n");
+ test_match ("a\n", "a\n");
+ test_match ("\nb", "\nb");
+ test_match ("a\nb", "a\nb");
+
+ TEST_SEARCH ("b", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
+ /* Valid use of special characters. */
+ test_match ("a*", "aa");
+ test_fastmap ("a*", "a", 0, 0);
+ TEST_REGISTERS ("a*", "aa", 0, 2, -1, -1, -1, -1);
+
+ test_match ("a*b", "aab");
+ test_fastmap ("a*b", "ab", 0, 0);
+
+ test_match ("a*ab", "aab");
+ TEST_REGISTERS ("a*a", "aa", 0, 2, -1, -1, -1, -1);
+ TEST_REGISTERS ("a*a", "xaax", 1, 3, -1, -1, -1, -1);
+
+ test_match ("\\{", "{");
+ test_match ("\\^", "^");
+ test_match ("\\.", ".");
+ test_match ("\\*", "*");
+ test_match ("\\[", "[");
+ test_match ("\\$", "$");
+ test_match ("\\\\", "\\");
+
+ test_match ("ab*", "a");
+ test_match ("ab*", "abb");
+
+ /* Valid consecutive repetitions. */
+ test_match ("a**", "a");
+ /* Valid period. */
+ test_match (".", "a");
+ TEST_REGISTERS (".", "a", 0, 1, -1, -1, -1, -1);
+ test_match (".", "\004");
+ test_match (".", "\n");
+ /* Valid bracket expressions. */
+ test_match ("[ab]", "a");
+ test_match ("[ab]", "b");
+ test_fastmap ("[ab]", "ab", 0, 0);
+ TEST_REGISTERS ("[ab]", "a", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ab]", "xax", 1, 2, -1, -1, -1, -1);
+
+ test_fastmap ("[^ab]", "ab", 1, 1);
+ test_match ("[^ab]", "c");
+ test_match ("[^a]", "\n");
+
+ test_match ("[a]*a", "aa");
+
+ test_match ("[[]", "[");
+ test_match ("[]]", "]");
+ test_match ("[.]", ".");
+ test_match ("[*]", "*");
+ test_match ("[\\]", "\\");
+ test_match ("[\\(]", "(");
+ test_match ("[\\)]", ")");
+ test_match ("[^]]", "a");
+ test_match ("[a^]", "^");
+ test_match ("[a$]", "$");
+ test_match ("[]a]", "]");
+ test_match ("[a][]]", "a]");
+ test_match ("[\n]", "\n");
+ test_match ("[^a]", "\n");
+ test_match ("[a-]", "a");
+
+ TEST_REGISTERS ("\\`[ \t\n]*", " karl (Karl Berry)", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ \t\n]*\\'", " karl (Karl Berry)", 18, 18, -1, -1, -1, -1);
+
+ /* Collating, noncollating,
+ equivalence classes aren't
+ implemented yet. */
+
+
+ /* Character classes. */
+ test_match ("[:alpha:]", "p");
+ test_match ("[[:alpha:]]", "a");
+ test_match ("[[:alpha:]]", "z");
+ test_match ("[[:alpha:]]", "A");
+ test_match ("[[:alpha:]]", "Z");
+ test_match ("[[:upper:]]", "A");
+ test_match ("[[:upper:]]", "Z");
+ test_match ("[[:lower:]]", "a");
+ test_match ("[[:lower:]]", "z");
+
+ test_match ("[[:digit:]]", "0");
+ test_match ("[[:digit:]]", "9");
+ test_fastmap ("[[:digit:]]", "0123456789", 0, 0);
+
+ test_match ("[[:alnum:]]", "0");
+ test_match ("[[:alnum:]]", "9");
+ test_match ("[[:alnum:]]", "a");
+ test_match ("[[:alnum:]]", "z");
+ test_match ("[[:alnum:]]", "A");
+ test_match ("[[:alnum:]]", "Z");
+ test_match ("[[:xdigit:]]", "0");
+ test_match ("[[:xdigit:]]", "9");
+ test_match ("[[:xdigit:]]", "A");
+ test_match ("[[:xdigit:]]", "F");
+ test_match ("[[:xdigit:]]", "a");
+ test_match ("[[:xdigit:]]", "f");
+ test_match ("[[:space:]]", " ");
+ test_match ("[[:print:]]", " ");
+ test_match ("[[:print:]]", "~");
+ test_match ("[[:punct:]]", ",");
+ test_match ("[[:graph:]]", "!");
+ test_match ("[[:graph:]]", "~");
+ test_match ("[[:cntrl:]]", "\177");
+ test_match ("[[:digit:]a]", "a");
+ test_match ("[[:digit:]a]", "2");
+ test_match ("[a[:digit:]]", "a");
+ test_match ("[a[:digit:]]", "2");
+ test_match ("[[:]", "[");
+ test_match ("[:]", ":");
+ test_match ("[[:a]", "[");
+ test_match ("[[:alpha:a]", "[");
+ /* Valid ranges. */
+ test_match ("[a-a]", "a");
+ test_fastmap ("[a-a]", "a", 0, 0);
+ TEST_REGISTERS ("[a-a]", "xax", 1, 2, -1, -1, -1, -1);
+
+ test_match ("[a-z]", "z");
+ test_fastmap ("[a-z]", "abcdefghijklmnopqrstuvwxyz", 0, 0);
+ test_match ("[-a]", "-"); /* First */
+ test_match ("[-a]", "a");
+ test_match ("[a-]", "-"); /* Last */
+ test_match ("[a-]", "a");
+ test_match ("[--@]", "@"); /* First and starting point. */
+
+ test_match ("[%--a]", "%"); /* Ending point. */
+ test_match ("[%--a]", "-"); /* Ditto. */
+
+ test_match ("[a%--]", "%"); /* Both ending point and last. */
+ test_match ("[a%--]", "-");
+ test_match ("[%--a]", "a"); /* Ending point only. */
+ test_match ("[a-c-f]", "e"); /* Piggyback. */
+
+ test_match ("[)-+--/]", "*");
+ test_match ("[)-+--/]", ",");
+ test_match ("[)-+--/]", "/");
+ test_match ("[[:digit:]-]", "-");
+ /* Concatenation ????*/
+ test_match ("[ab][cd]", "ac");
+ test_fastmap ("[ab][cd]", "ab", 0, 0);
+ TEST_REGISTERS ("[ab][cd]", "ad", 0, 2, -1, -1, -1, -1);
+ TEST_REGISTERS ("[ab][cd]", "xadx", 1, 3, -1, -1, -1, -1);
+
+ /* Valid expression anchoring. */
+ test_match ("^a", "a");
+ test_fastmap ("^a", "a", 0, 0);
+ TEST_REGISTERS ("^a", "ax", 0, 1, -1, -1, -1, -1);
+
+ test_match ("^", "");
+ TEST_REGISTERS ("^", "", 0, 0, -1, -1, -1, -1);
+ test_match ("$", "");
+ TEST_REGISTERS ("$", "", 0, 0, -1, -1, -1, -1);
+
+ test_match ("a$", "a");
+ test_fastmap ("a$", "a", 0, 0);
+ TEST_REGISTERS ("a$", "xa", 1, 2, -1, -1, -1, -1);
+
+ test_match ("^ab$", "ab");
+ test_fastmap ("^ab$", "a", 0, 0);
+ TEST_REGISTERS ("^a$", "a", 0, 1, -1, -1, -1, -1);
+
+ test_fastmap ("^$", "", 0, 0);
+ test_match ("^$", "");
+ TEST_REGISTERS ("^$", "", 0, 0, -1, -1, -1, -1);
+
+ TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ba", 0, 2);
+
+ /* Two strings. */
+ test_match_2 ("ab", "a", "b");
+ TEST_REGISTERS_2 ("ab", "a", "b", 0, 2, -1, -1, -1, -1);
+
+ test_match_2 ("a", "", "a");
+ test_match_2 ("a", "a", "");
+ test_match_2 ("ab", "a", "b");
+ /* (start)pos. */
+ TEST_POSITIONED_MATCH ("b", "ab", 1);
+ /* mstop. */
+ TEST_TRUNCATED_MATCH ("a", "ab", 1);
+
+
+ /* Both basic and extended, continued; should not match. */
+
+ test_should_match = false;
+ /* Ordinary characters. */
+ test_match ("abc", "ab");
+
+ TEST_SEARCH ("c", "ab", 0, 2);
+ TEST_SEARCH ("c", "ab", 0, 2);
+ TEST_SEARCH ("c", "ab", 1, -2);
+ TEST_SEARCH ("c", "ab", 0, 10);
+ TEST_SEARCH ("c", "ab", 1, -10);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 0, 2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
+ TEST_SEARCH_2 ("c", "a", "b", 1, -2, 2);
+
+ TEST_SEARCH ("c", "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 236, -237);
+
+ /* Invalid use of special characters. */
+ invalid_pattern (REG_EESCAPE, "\\");
+ invalid_pattern (REG_EESCAPE, "a\\");
+ invalid_pattern (REG_EESCAPE, "a*\\");
+ /* Invalid period. */
+ test_match (".", "");
+ /* Invalid bracket expressions. */
+ test_match ("[ab]", "c");
+ test_match ("[^b]", "b");
+ test_match ("[^]]", "]");
+
+ invalid_pattern (REG_EBRACK, "[");
+ invalid_pattern (REG_EBRACK, "[^");
+ invalid_pattern (REG_EBRACK, "[a");
+ invalid_pattern (REG_EBRACK, "[]");
+ invalid_pattern (REG_EBRACK, "[]a");
+ invalid_pattern (REG_EBRACK, "a[]a");
+
+
+ test_match ("[:alpha:]", "q"); /* Character classes. */
+ test_match ("[[:alpha:]]", "2");
+ test_match ("[[:upper:]]", "a");
+ test_match ("[[:lower:]]", "A");
+ test_match ("[[:digit:]]", "a");
+ test_match ("[[:alnum:]]", ":");
+ test_match ("[[:xdigit:]]", "g");
+ test_match ("[[:space:]]", "a");
+ test_match ("[[:print:]]", "\177");
+ test_match ("[[:punct:]]", "a");
+ test_match ("[[:graph:]]", " ");
+ test_match ("[[:cntrl:]]", "a");
+ invalid_pattern (REG_EBRACK, "[[:");
+ invalid_pattern (REG_EBRACK, "[[:alpha:");
+ invalid_pattern (REG_EBRACK, "[[:alpha:]");
+ invalid_pattern (REG_ECTYPE, "[[::]]");
+ invalid_pattern (REG_ECTYPE, "[[:a:]]");
+ invalid_pattern (REG_ECTYPE, "[[:alpo:]]");
+ invalid_pattern (REG_ECTYPE, "[[:a:]");
+
+ test_match ("[a-z]", "2"); /* Invalid ranges. */
+ test_match ("[^-a]", "-");
+ test_match ("[^a-]", "-");
+ test_match ("[)-+--/]", ".");
+ invalid_pattern (REG_ERANGE, "[z-a]"); /* Empty */
+ invalid_pattern (REG_ERANGE, "[a--]"); /* Empty */
+ invalid_pattern (REG_ERANGE, "[[:digit:]-9]");
+ invalid_pattern (REG_ERANGE, "[a-[:alpha:]]");
+ invalid_pattern (REG_ERANGE, "[a-");
+ invalid_pattern (REG_EBRACK, "[a-z");
+
+ test_match ("[ab][cd]", "ae"); /* Concatenation. */
+ test_match ("b*c", "b"); /* Star. */
+
+ /* Invalid anchoring. */
+ test_match ("^", "a");
+ test_match ("^a", "ba");
+ test_match ("$", "b");
+ test_match ("a$", "ab");
+ test_match ("^$", "a");
+ test_match ("^ab$", "a");
+
+ TEST_SEARCH ("^a", "b\na", 0, 3);
+ TEST_SEARCH ("b$", "b\na", 0, 3);
+
+ test_match_2 ("^a", "\n", "a");
+ test_match_2 ("a$", "a", "\n");
+
+ TEST_SEARCH (PARENS_TO_OPS ("(^a)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("^(^a)"), "ba", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)$"), "ab", 0, 2);
+
+ printf ("\nFinished generic POSIX tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/psx-group.c b/gnu/lib/libregex/test/psx-group.c
new file mode 100644
index 0000000..08ae8a2
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-group.c
@@ -0,0 +1,440 @@
+/* psx-group.c: test POSIX grouping, both basic and extended. */
+
+#include "test.h"
+
+
+void
+test_grouping ()
+{
+ printf ("\nStarting POSIX grouping tests.\n");
+
+ test_should_match = true;
+
+ test_fastmap (PARENS_TO_OPS ("(a)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "a", 0, 1, 0, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)"), "xax", 1, 2, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a))"), "a");
+ test_fastmap (PARENS_TO_OPS ("((a))"), "a", 0, 0);
+ TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "a", 0, 1, 0, 1, 0, 1);
+ TEST_REGISTERS (PARENS_TO_OPS ("((a))"), "xax", 1, 2, 1, 2, 1, 2);
+
+ test_fastmap (PARENS_TO_OPS ("(a)(b)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)(b)"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "ab", 0, 2, 0, 1, 1, 2);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)(b)"), "xabx", 1, 3, 1, 2, 2, 3);
+
+ test_all_registers (PARENS_TO_OPS ("((a)(b))"), "ab", "", 0, 2, 0, 2, 0, 1,
+ 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+
+ /* Test that we simply ignore groups past the 255th. */
+ test_match (PARENS_TO_OPS ("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))"), "a");
+
+
+ /* Per POSIX D11.1, p. 125. */
+
+ test_fastmap (PARENS_TO_OPS ("(a)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "", 0, 0, -1, -1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*"), "aa", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "", 0, 0, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)"), "a", 0, 1, 0, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "b", 0, 1, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)b"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "ab", 0, 2, 0, 2, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abb");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abb", 0, 3, 2, 3, 2, 2);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "aabab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "aabab", 0, 5, 3, 5, 3, 4);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abbab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abbab", 0, 5, 3, 5, 3, 4);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)b)*"), "abaabaaaab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b)*"), "abaabaaab", 0, 9, 5, 9, 5, 8);
+
+ test_fastmap (PARENS_TO_OPS ("(ab)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab)*"), "abab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "abab", 0, 4, 2, 4, -1, -1);
+
+ /* We match the empty string here. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab)*"), "xababx", 0, 0, -1, -1, -1, -1);
+
+ /* Per David A. Willcox. */
+ TEST_REGISTERS (PARENS_TO_OPS ("a(b*)c"), "ac", 0, 2, 1, 1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "b", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*b"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ test_match_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab");
+ TEST_REGISTERS_2 (PARENS_TO_OPS ("(a)*b"), "a", "ab", 0, 3, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*b"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*b"), "aab", 0, 3, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*a"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*a"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*a"), "a", 0, 1, -1, -1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*))*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*))*"), "", 0, 0, 0, 0, 0, 0);
+ test_match (PARENS_TO_OPS ("((a*))*"), "aa");
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "b", 0, 1, 0, 0, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xbx", 1, 2, 1, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*b"), "ab"); /* Per rms. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "ab", 0, 2, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "xabx", 1, 3, 1, 2, -1, -1);
+
+ /* Test register restores. */
+ test_match (PARENS_TO_OPS ("(a*)*b"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b"), "aab", 0, 3, 0, 2, -1, -1);
+
+ TEST_REGISTERS_2 (PARENS_TO_OPS ("(a*)*b"), "a", "ab", 0, 3, 0, 2, -1, -1);
+
+ /* We are matching the empty string, with backtracking. */
+ test_fastmap (PARENS_TO_OPS ("(a*)a"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)a"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "a", 0, 1, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)a"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)a"), "aa", 0, 2, 0, 1, -1, -1);
+
+ /* We are matching the empty string, with backtracking. */
+/*fails test_match (PARENS_TO_OPS ("(a*)*a"), "a"); */
+ test_match (PARENS_TO_OPS ("(a*)*a"), "aa");
+ /* Match the empty string. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "a", 0, 1, 0, 0, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xax", 1, 2, 1, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "aa", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*a"), "xaax", 1, 3, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a)*ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "ab", 0, 2, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a)*ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS("(a)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a*)ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "ab", 0, 2, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*ab"), "a", 0 , 0);
+ test_match (PARENS_TO_OPS ("(a*)*ab"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "ab", 0, 2, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*ab"), "aab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*ab"), "aab", 0, 3, 0, 1, -1, -1);
+
+ TEST_REGISTERS (PARENS_TO_OPS("(a*)*ab"), "xaabx", 1, 4, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*b*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*b*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*b*c"), "c", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a)*(ab)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a)*(ab)*"), "ab");
+ /* Register 1 doesn't match at all (vs. matching the empty string)
+ because of backtracking, hence -1's. */
+ TEST_REGISTERS (PARENS_TO_OPS ("(a)*(ab)*"), "ab", 0, 2, -1, -1, 0, 2);
+
+ test_match (PARENS_TO_OPS ("(a*)*(ab)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*(ab)*"), "ab", 0, 2, 0, 0, 0, 2);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "b", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*"), "baab", 0, 4, 1, 4, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "a", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "ba");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ba", 0, 2, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aa", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "bb");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "bb", 0, 2, 0, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "aba");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "aba", 0, 3, 2, 3, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b*)b"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)b"), "b", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)*(b*)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "", "", 0, 0, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba");
+ /* Perhaps register 3 should be 3/3 here? Not sure if standard
+ specifies this. xx*/
+ test_all_registers (PARENS_TO_OPS ("((a*)*(b*)*)*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)(b*))*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)(b*))*"), "");
+
+ test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "", "", 0, 0, 0, 0,
+ 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
+
+ test_match (PARENS_TO_OPS ("((a*)(b*))*"), "aba");
+ test_all_registers (PARENS_TO_OPS ("((a*)(b*))*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*(b)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "", "", 0, 0, 0, 0,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*(b)*)*"), "aba");
+
+ test_all_registers (PARENS_TO_OPS ("((a)*(b)*)*"), "aba", "", 0, 3, 2, 3,
+ 2, 3, 1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", 0, 0);
+ test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "", "", 0, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c");
+ test_all_registers (PARENS_TO_OPS ("(c(a)*(b)*)*"), "c", "", 0, 1, 0, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", 0, 0);
+ test_match (PARENS_TO_OPS ("c((a)*(b)*)*"), "c");
+ test_all_registers (PARENS_TO_OPS ("c((a)*(b)*)*"), "c", "", 0, 1, 1, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(((a)*(b)*)*)*"), "", "", 0, 0, 0, 0,
+ 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "");
+ test_fastmap (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "c", 0, 0);
+
+ test_all_registers (PARENS_TO_OPS ("(c(c(a)*(b)*)*)*"), "", "", 0, 0, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "");
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "abb");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abb", 0, 3, 2, 3, 0, 1); /*zz*/
+
+ test_match (PARENS_TO_OPS ("((a)*b)*"), "abbab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "abbab", 0, 5, 3, 5, 3, 4);
+
+ /* We match the empty string here. */
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*"), "xabbabx", 0, 0, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*)*"), "aa", 0, 2, 0, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)*)*"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_fastmap (PARENS_TO_OPS ("(ab*)*"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "", 0, 0, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*"), "aa");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*"), "aa", 0, 2, 1, 2, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(ab*)*c"), "ac", 0, 0);
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abbac");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abbac", 0, 5, 3, 4, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abac");
+ TEST_REGISTERS (PARENS_TO_OPS ("(ab*)*c"), "abac", 0, 4, 2, 3, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b)*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "bbc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "bbc", 0, 3, 1, 2, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "aababc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aababc", 0, 6, 3, 5, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(a*b)*c"), "aabaabc");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b)*c"), "aabaabc", 0, 7, 3, 6, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b*)"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "", 0, 0, 0, 0, 0, 0);
+
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)"), "b", 0, 1, 0, 1, 0, 0);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "", 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "a");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "a", 0, 1, 0, 1, 0, 1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "b");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "b", 0, 1, 0, 1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("((a)*b*)"), "ab");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)"), "ab", 0, 2, 0, 2, 0, 1);
+
+ test_fastmap (PARENS_TO_OPS ("((a*)b*)c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a*)b*)c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a*)b*)c"), "c", 0, 1, 0, 0, 0, 0);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b*)c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b*)c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b*)c"), "c", 0, 1, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(a*b*)*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "");
+ TEST_REGISTERS (PARENS_TO_OPS ("(a*b*)*"), "", 0, 0, 0, 0, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(((a*))((b*)))*"), "ab", 0, 0);
+ test_match (PARENS_TO_OPS ("(((a*))((b*)))*"), "");
+ test_all_registers (PARENS_TO_OPS ("(((a*))((b*)))*"), "", "", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "abcde", 0, 0);
+ test_match (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "");
+ test_all_registers (PARENS_TO_OPS ("(c*((a*))d*((b*))e*)*"), "", "", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1);
+
+ test_fastmap (PARENS_TO_OPS ("((a)*b)*c"), "abc", 0, 0);
+ test_match (PARENS_TO_OPS ("((a)*b)*c"), "c");
+ TEST_REGISTERS (PARENS_TO_OPS ("((a)*b)*c"), "c", 0, 1, -1, -1, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(ab)*"), "");
+ test_match (PARENS_TO_OPS ("((ab)*)"), "");
+ test_match (PARENS_TO_OPS ("(((ab)*))"), "");
+ test_match (PARENS_TO_OPS ("((((ab)*)))"), "");
+ test_match (PARENS_TO_OPS ("(((((ab)*))))"), "");
+ test_match (PARENS_TO_OPS ("((((((ab)*)))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((ab)*))))))"), "");
+ test_match (PARENS_TO_OPS ("((((((((ab)*)))))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
+
+
+ test_fastmap (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "a", 0, 0);
+ test_match (PARENS_TO_OPS ("((((((((((ab)*)))))))))"), "");
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "");
+ test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "", NULL,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1);
+
+ test_match (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab");
+ test_all_registers (PARENS_TO_OPS ("(((((((((ab)*))))))))"), "abab", NULL,
+ 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 2, 4);
+
+
+ test_should_match = false;
+
+ invalid_pattern (REG_EPAREN, PARENS_TO_OPS ("(a"));
+
+ test_match (PARENS_TO_OPS ("(a)"), "");
+ test_match (PARENS_TO_OPS ("((a))"), "b");
+ test_match (PARENS_TO_OPS ("(a)(b)"), "ac");
+ test_match (PARENS_TO_OPS ("(ab)*"), "acab");
+ test_match (PARENS_TO_OPS ("(a*)*b"), "c");
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baa");
+ test_match (PARENS_TO_OPS ("(a*b)*"), "baabc");
+ test_match (PARENS_TO_OPS ("(a*b*)*"), "c");
+ test_match (PARENS_TO_OPS ("((a*)*(b*)*)*"), "c");
+ test_match (PARENS_TO_OPS ("(a*)*"), "ab");
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "ab");
+ test_match (PARENS_TO_OPS ("((a*)*)*"), "b");
+ test_match (PARENS_TO_OPS ("(ab*)*"), "abc");
+ test_match (PARENS_TO_OPS ("(ab*)*c"), "abbad");
+ test_match (PARENS_TO_OPS ("(a*c)*b"), "aacaacd");
+ test_match (PARENS_TO_OPS ("(a*)"), "b");
+ test_match (PARENS_TO_OPS ("((a*)b*)"), "c");
+
+ /* Expression anchoring. */
+ TEST_SEARCH (PARENS_TO_OPS ("(^b)"), "ab", 0, 2);
+ TEST_SEARCH (PARENS_TO_OPS ("(a$)"), "ab", 0, 2);
+
+ printf ("\nFinished POSIX grouping tests.\n");
+}
diff --git a/gnu/lib/libregex/test/psx-interf.c b/gnu/lib/libregex/test/psx-interf.c
new file mode 100644
index 0000000..80498fb
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-interf.c
@@ -0,0 +1,624 @@
+/* psx-interf.c: test POSIX interface. */
+
+#include <string.h>
+#include <assert.h>
+
+#include "test.h"
+
+#define ERROR_CODE_LENGTH 20
+#define TEST_ERRBUF_SIZE 15
+
+
+void test_compile ();
+
+
+/* ANSWER should be at least ERROR_CODE_LENGTH long. */
+
+static char *
+get_error_string (error_code, answer)
+ int error_code;
+ char answer[];
+{
+ switch (error_code)
+ {
+ case 0: strcpy (answer, "No error"); break;
+ case REG_NOMATCH: strcpy (answer, "REG_NOMATCH"); break;
+ case REG_BADPAT: strcpy (answer, "REG_BADPAT"); break;
+ case REG_EPAREN: strcpy (answer, "REG_EPAREN"); break;
+ case REG_ESPACE: strcpy (answer, "REG_ESPACE"); break;
+ case REG_ECOLLATE: strcpy (answer, "REG_ECOLLATE"); break;
+ case REG_ECTYPE: strcpy (answer, "REG_ECTYPE"); break;
+ case REG_EESCAPE: strcpy (answer, "REG_EESCAPE"); break;
+ case REG_ESUBREG: strcpy (answer, "REG_ESUBREG"); break;
+ case REG_EBRACK: strcpy (answer, "REG_EBRACK"); break;
+ case REG_EBRACE: strcpy (answer, "REG_EBRACE"); break;
+ case REG_BADBR: strcpy (answer, "REG_BADBR"); break;
+ case REG_ERANGE: strcpy (answer, "REG_ERANGE"); break;
+ case REG_BADRPT: strcpy (answer, "REG_BADRPT"); break;
+ case REG_EEND: strcpy (answer, "REG_EEND"); break;
+ default: strcpy (answer, "Bad error code");
+ }
+ return answer;
+}
+
+
+/* I don't think we actually need to initialize all these things.
+ --karl */
+
+void
+init_pattern_buffer (pattern_buffer_ptr)
+ regex_t *pattern_buffer_ptr;
+{
+ pattern_buffer_ptr->buffer = NULL;
+ pattern_buffer_ptr->allocated = 0;
+ pattern_buffer_ptr->used = 0;
+ pattern_buffer_ptr->fastmap = NULL;
+ pattern_buffer_ptr->fastmap_accurate = 0;
+ pattern_buffer_ptr->translate = NULL;
+ pattern_buffer_ptr->can_be_null = 0;
+ pattern_buffer_ptr->re_nsub = 0;
+ pattern_buffer_ptr->no_sub = 0;
+ pattern_buffer_ptr->not_bol = 0;
+ pattern_buffer_ptr->not_eol = 0;
+}
+
+
+void
+test_compile (valid_pattern, error_code_expected, pattern,
+ pattern_buffer_ptr, cflags)
+ unsigned valid_pattern;
+ int error_code_expected;
+ const char *pattern;
+ regex_t *pattern_buffer_ptr;
+ int cflags;
+{
+ int error_code_returned;
+ boolean error = false;
+ char errbuf[TEST_ERRBUF_SIZE];
+
+ init_pattern_buffer (pattern_buffer_ptr);
+ error_code_returned = regcomp (pattern_buffer_ptr, pattern, cflags);
+
+ if (valid_pattern && error_code_returned)
+ {
+ printf ("\nShould have been a valid pattern but wasn't.\n");
+ regerror (error_code_returned, pattern_buffer_ptr, errbuf,
+ TEST_ERRBUF_SIZE);
+ printf ("%s", errbuf);
+ error = true;
+ }
+
+ if (!valid_pattern && !error_code_returned)
+ {
+ printf ("\n\nInvalid pattern compiled as valid:\n");
+ error = true;
+ }
+
+ if (error_code_returned != error_code_expected)
+ {
+ char expected_error_string[ERROR_CODE_LENGTH];
+ char returned_error_string[ERROR_CODE_LENGTH];
+
+ get_error_string (error_code_expected, expected_error_string),
+ get_error_string (error_code_returned, returned_error_string);
+
+ printf (" Expected error code %s but got `%s'.\n",
+ expected_error_string, returned_error_string);
+
+ error = true;
+ }
+
+ if (error)
+ print_pattern_info (pattern, pattern_buffer_ptr);
+}
+
+
+static void
+test_nsub (sub_count, pattern, cflags)
+ unsigned sub_count;
+ char *pattern;
+ int cflags;
+
+{
+ regex_t pattern_buffer;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+
+ if (pattern_buffer.re_nsub != sub_count)
+ {
+ printf ("\nShould have counted %d subexpressions but counted %d \
+instead.\n", sub_count, pattern_buffer.re_nsub);
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_regcomp ()
+{
+ regex_t pattern_buffer;
+ int cflags = 0;
+
+
+ printf ("\nStarting regcomp tests.\n");
+
+ cflags = 0;
+ test_compile (0, REG_ESUBREG, "\\(a\\)\\2", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
+ test_compile (0, REG_BADBR, "a\\{-1\\}", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACE, "a\\{1", &pattern_buffer, cflags);
+
+ cflags = REG_EXTENDED;
+ test_compile (0, REG_ECTYPE, "[[:alpo:]]", &pattern_buffer, cflags);
+ test_compile (0, REG_EESCAPE, "\\", &pattern_buffer, cflags);
+ test_compile (0, REG_EBRACK, "[a", &pattern_buffer, cflags);
+ test_compile (0, REG_EPAREN, "(", &pattern_buffer, cflags);
+ test_compile (0, REG_ERANGE, "[z-a]", &pattern_buffer, cflags);
+
+ test_nsub (1, "(a)", cflags);
+ test_nsub (2, "((a))", cflags);
+ test_nsub (2, "(a)(b)", cflags);
+
+ cflags = REG_EXTENDED | REG_NOSUB;
+ test_nsub (1, "(a)", cflags);
+
+ regfree (&pattern_buffer);
+
+ printf ("\nFinished regcomp tests.\n");
+}
+
+
+static void
+fill_pmatch (pmatch, start0, end0, start1, end1, start2, end2)
+ regmatch_t pmatch[];
+ regoff_t start0, end0, start1, end1, start2, end2;
+{
+ pmatch[0].rm_so = start0;
+ pmatch[0].rm_eo = end0;
+ pmatch[1].rm_so = start1;
+ pmatch[1].rm_eo = end1;
+ pmatch[2].rm_so = start2;
+ pmatch[2].rm_eo = end2;
+}
+
+
+static void
+test_pmatch (pattern, string, nmatch, pmatch, correct_pmatch, cflags)
+ char *pattern;
+ char *string;
+ unsigned nmatch;
+ regmatch_t pmatch[];
+ regmatch_t correct_pmatch[];
+ int cflags;
+{
+ regex_t pattern_buffer;
+ unsigned this_match;
+ int error_code_returned;
+ boolean found_nonmatch = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, nmatch, pmatch, 0);
+
+ if (error_code_returned == REG_NOMATCH)
+ printf ("Matching failed in test_pmatch.\n");
+ else
+ {
+ for (this_match = 0; this_match < nmatch; this_match++)
+ {
+ if (pmatch[this_match].rm_so != correct_pmatch[this_match].rm_so)
+ {
+ if (found_nonmatch == false)
+ printf ("\n");
+
+ printf ("Pmatch start %d wrong: was %d when should have \
+been %d.\n", this_match, pmatch[this_match].rm_so,
+ correct_pmatch[this_match].rm_so);
+ found_nonmatch = true;
+ }
+ if (pmatch[this_match].rm_eo != correct_pmatch[this_match].rm_eo)
+ {
+ if (found_nonmatch == false)
+ printf ("\n");
+
+ printf ("Pmatch end %d wrong: was %d when should have been \
+%d.\n", this_match, pmatch[this_match].rm_eo,
+ correct_pmatch[this_match].rm_eo);
+ found_nonmatch = true;
+ }
+ }
+
+ if (found_nonmatch)
+ {
+ printf (" The number of pmatches requested was: %d.\n", nmatch);
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+ }
+ } /* error_code_returned == REG_NOMATCH */
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_eflags (must_match_bol, must_match_eol, pattern, string, cflags, eflags)
+ boolean must_match_bol;
+ boolean must_match_eol;
+ char *pattern;
+ char *string;
+ int cflags;
+ int eflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+ boolean was_error = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, eflags);
+
+ if (error_code_returned == REG_NOMATCH)
+ {
+ /* If wasn't true that both 1) the anchored part of the pattern
+ had to match this string and 2) this string was a proper
+ substring... */
+
+ if (!( (must_match_bol && (eflags & REG_NOTBOL))
+ || (must_match_eol && (eflags & REG_NOTEOL)) ))
+ {
+ printf ("\nEflags test failed: didn't match when should have.\n");
+ was_error = true;
+ }
+ }
+ else /* We got a match. */
+ {
+ /* If wasn't true that either 1) the anchored part of the pattern
+ didn't have to match this string or 2) this string wasn't a
+ proper substring... */
+
+ if ((must_match_bol == (eflags & REG_NOTBOL))
+ || (must_match_eol == (eflags & REG_NOTEOL)))
+ {
+ printf ("\nEflags test failed: matched when shouldn't have.\n");
+ was_error = true;
+ }
+ }
+
+ if (was_error)
+ {
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (eflags & REG_NOTBOL)
+ printf (" The eflag REG_BOL was set.\n");
+ if (eflags & REG_NOTEOL)
+ printf (" The eflag REG_EOL was set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_ignore_case (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nIgnore-case test failed:\n");
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (cflags & REG_ICASE)
+ printf (" The cflag REG_ICASE was set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_newline (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nNewline test failed:\n");
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+
+ if (cflags & REG_NEWLINE)
+ printf (" The cflag REG_NEWLINE was set.\n");
+ else
+ printf (" The cflag REG_NEWLINE wasn't set.\n");
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_posix_match (should_match, pattern, string, cflags)
+ boolean should_match;
+ char *pattern;
+ char *string;
+ int cflags;
+{
+ regex_t pattern_buffer;
+ int error_code_returned;
+ boolean was_error = false;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+ error_code_returned = regexec (&pattern_buffer, string, 0, 0, 0);
+
+ if (should_match && error_code_returned == REG_NOMATCH)
+ {
+ printf ("\nShould have matched but didn't:\n");
+ was_error = true;
+ }
+ else if (!should_match && error_code_returned != REG_NOMATCH)
+ {
+ printf ("\nShould not have matched but did:\n");
+ was_error = true;
+ }
+
+ if (was_error)
+ {
+ printf (" The string to match was: `%s'.\n", string);
+ print_pattern_info (pattern, &pattern_buffer);
+ }
+
+ regfree (&pattern_buffer);
+}
+
+
+static void
+test_regexec ()
+{
+ regmatch_t pmatch[3];
+ regmatch_t correct_pmatch[3];
+ int cflags = 0;
+ int eflags = 0;
+
+ printf ("\nStarting regexec tests.\n");
+
+ cflags = REG_NOSUB; /* shouldn't look at any of pmatch. */
+ test_pmatch ("a", "a", 0, pmatch, correct_pmatch, cflags);
+
+ /* Ask for less `pmatch'es than there are pattern subexpressions.
+ (Shouldn't look at pmatch[2]. */
+ cflags = REG_EXTENDED;
+ fill_pmatch (correct_pmatch, 0, 1, 0, 1, 100, 101);
+ test_pmatch ("((a))", "a", 2, pmatch, correct_pmatch, cflags);
+
+ /* Ask for same number of `pmatch'es as there are pattern subexpressions. */
+ cflags = REG_EXTENDED;
+ fill_pmatch(correct_pmatch, 0, 1, 0, 1, -1, -1);
+ test_pmatch ("(a)", "a", 2, pmatch, correct_pmatch, cflags);
+
+ /* Ask for more `pmatch'es than there are pattern subexpressions. */
+ cflags = REG_EXTENDED;
+ fill_pmatch (correct_pmatch, 0, 1, -1, -1, -1, -1);
+ test_pmatch ("a", "a", 2, pmatch, correct_pmatch, cflags);
+
+ eflags = REG_NOTBOL;
+ test_eflags (true, false, "^a", "a", cflags, eflags);
+ test_eflags (true, false, "(^a)", "a", cflags, eflags);
+ test_eflags (true, false, "a|^b", "b", cflags, eflags);
+ test_eflags (true, false, "^b|a", "b", cflags, eflags);
+
+ eflags = REG_NOTEOL;
+ test_eflags (false, true, "a$", "a", cflags, eflags);
+ test_eflags (false, true, "(a$)", "a", cflags, eflags);
+ test_eflags (false, true, "a|b$", "b", cflags, eflags);
+ test_eflags (false, true, "b$|a", "b", cflags, eflags);
+
+ eflags = REG_NOTBOL | REG_NOTEOL;
+ test_eflags (true, true, "^a$", "a", cflags, eflags);
+ test_eflags (true, true, "(^a$)", "a", cflags, eflags);
+ test_eflags (true, true, "a|(^b$)", "b", cflags, eflags);
+ test_eflags (true, true, "(^b$)|a", "b", cflags, eflags);
+
+ cflags = REG_ICASE;
+ test_ignore_case (true, "a", "a", cflags);
+ test_ignore_case (true, "A", "A", cflags);
+ test_ignore_case (true, "A", "a", cflags);
+ test_ignore_case (true, "a", "A", cflags);
+
+ test_ignore_case (true, "@", "@", cflags);
+ test_ignore_case (true, "\\[", "[", cflags);
+ test_ignore_case (true, "`", "`", cflags);
+ test_ignore_case (true, "{", "{", cflags);
+
+ test_ignore_case (true, "[!-`]", "A", cflags);
+ test_ignore_case (true, "[!-`]", "a", cflags);
+
+ cflags = 0;
+ test_ignore_case (false, "a", "a", cflags);
+ test_ignore_case (false, "A", "A", cflags);
+ test_ignore_case (false, "A", "a", cflags);
+ test_ignore_case (false, "a", "A", cflags);
+
+ test_ignore_case (true, "@", "@", cflags);
+ test_ignore_case (true, "\\[", "[", cflags);
+ test_ignore_case (true, "`", "`", cflags);
+ test_ignore_case (true, "{", "{", cflags);
+
+ test_ignore_case (true, "[!-`]", "A", cflags);
+ test_ignore_case (false, "[!-`]", "a", cflags);
+
+
+ /* Test newline stuff. */
+ cflags = REG_EXTENDED | REG_NEWLINE;
+ test_newline (true, "\n", "\n", cflags);
+ test_newline (true, "a\n", "a\n", cflags);
+ test_newline (true, "\nb", "\nb", cflags);
+ test_newline (true, "a\nb", "a\nb", cflags);
+
+ test_newline (false, ".", "\n", cflags);
+ test_newline (false, "[^a]", "\n", cflags);
+
+ test_newline (true, "\n^a", "\na", cflags);
+ test_newline (true, "\n(^a|b)", "\na", cflags);
+ test_newline (true, "a$\n", "a\n", cflags);
+ test_newline (true, "(a$|b)\n", "a\n", cflags);
+ test_newline (true, "(a$|b|c)\n", "a\n", cflags);
+ test_newline (true, "((a$|b|c)$)\n", "a\n", cflags);
+ test_newline (true, "((a$|b|c)$)\n", "b\n", cflags);
+ test_newline (true, "(a$|b)\n|a\n", "a\n", cflags);
+
+ test_newline (true, "^a", "\na", cflags);
+ test_newline (true, "a$", "a\n", cflags);
+
+ /* Now test normal behavior. */
+ cflags = REG_EXTENDED;
+ test_newline (true, "\n", "\n", cflags);
+ test_newline (true, "a\n", "a\n", cflags);
+ test_newline (true, "\nb", "\nb", cflags);
+ test_newline (true, "a\nb", "a\nb", cflags);
+
+ test_newline (true, ".", "\n", cflags);
+ test_newline (true, "[^a]", "\n", cflags);
+
+ test_newline (false, "\n^a", "\na", cflags);
+ test_newline (false, "a$\n", "a\n", cflags);
+
+ test_newline (false, "^a", "\na", cflags);
+ test_newline (false, "a$", "a\n", cflags);
+
+
+ /* Test that matches whole string only. */
+ cflags = 0;
+ test_posix_match (true, "a", "a", cflags);
+
+ /* Tests that match substrings. */
+ test_posix_match (true, "a", "ab", cflags);
+ test_posix_match (true, "b", "ab", cflags);
+
+ /* Test that doesn't match. */
+ test_posix_match (false, "a", "b", cflags);
+
+ printf ("\nFinished regexec tests.\n");
+}
+
+
+static void
+test_error_code_message (error_code, expected_error_message)
+ int error_code;
+ char *expected_error_message;
+{
+ char returned_error_message[TEST_ERRBUF_SIZE];
+ char error_code_string[ERROR_CODE_LENGTH];
+ size_t expected_error_message_length = strlen (expected_error_message) + 1;
+ size_t returned_error_message_length = regerror (error_code, 0,
+ returned_error_message,
+ TEST_ERRBUF_SIZE);
+
+ if (returned_error_message_length != expected_error_message_length)
+ {
+ printf ("\n\n Testing returned error codes, with expected error \
+message `%s':\n", expected_error_message);
+
+ printf ("\n\n and returned error message `%s':\n",
+ returned_error_message);
+ printf (" should have returned a length of %d but returned %d.\n",
+ expected_error_message_length, returned_error_message_length);
+ }
+
+ if (strncmp (expected_error_message, returned_error_message,
+ TEST_ERRBUF_SIZE - 1) != 0)
+ {
+
+ get_error_string (error_code, error_code_string),
+ printf ("\n\n With error code %s (%d), expected error message:\n",
+ error_code_string, error_code);
+
+ printf (" `%s'\n", expected_error_message);
+ printf (" but got:\n");
+ printf (" `%s'\n", returned_error_message);
+ }
+}
+
+
+static void
+test_error_code_allocation (error_code, expected_error_message)
+ int error_code;
+ char *expected_error_message;
+{
+ char *returned_error_message = NULL;
+ char error_code_string[ERROR_CODE_LENGTH];
+ size_t returned_error_message_length = regerror (error_code, 0,
+ returned_error_message,
+ (size_t)0);
+
+ returned_error_message = xmalloc (returned_error_message_length + 1);
+
+ regerror (error_code, 0, returned_error_message,
+ returned_error_message_length);
+
+ if (strcmp (expected_error_message, returned_error_message) != 0)
+ {
+ get_error_string (error_code, error_code_string),
+
+ printf ("\n\n Testing error code allocation,\n");
+ printf ("with error code %s (%d), expected error message:\n",
+ error_code_string, error_code);
+ printf (" `%s'\n", expected_error_message);
+ printf (" but got:\n");
+ printf (" `%s'\n", returned_error_message);
+ }
+}
+
+
+static void
+test_regerror ()
+{
+ test_error_code_message (REG_NOMATCH, "No match");
+ test_error_code_message (REG_BADPAT, "Invalid regular expression");
+ test_error_code_message (REG_ECOLLATE, "Invalid collation character");
+ test_error_code_message (REG_ECTYPE, "Invalid character class name");
+ test_error_code_message (REG_EESCAPE, "Trailing backslash");
+ test_error_code_message (REG_ESUBREG, "Invalid back reference");
+ test_error_code_message (REG_EBRACK, "Unmatched [ or [^");
+ test_error_code_message (REG_EPAREN, "Unmatched ( or \\(");
+ test_error_code_message (REG_EBRACE, "Unmatched \\{");
+ test_error_code_message (REG_BADBR, "Invalid content of \\{\\}");
+ test_error_code_message (REG_ERANGE, "Invalid range end");
+ test_error_code_message (REG_ESPACE, "Memory exhausted");
+ test_error_code_message (REG_BADRPT, "Invalid preceding regular expression");
+ test_error_code_message (REG_EEND, "Premature end of regular expression");
+ test_error_code_message (REG_ESIZE, "Regular expression too big");
+ test_error_code_allocation (REG_ERPAREN, "Unmatched ) or \\)");
+}
+
+
+void
+test_posix_interface ()
+{
+ printf ("\nStarting POSIX interface tests.\n");
+ t = posix_interface_test;
+
+ test_regcomp ();
+ test_regexec ();
+ test_regerror ();
+
+ printf ("\nFinished POSIX interface tests.\n");
+}
diff --git a/gnu/lib/libregex/test/psx-interv.c b/gnu/lib/libregex/test/psx-interv.c
new file mode 100644
index 0000000..fcdf488
--- /dev/null
+++ b/gnu/lib/libregex/test/psx-interv.c
@@ -0,0 +1,140 @@
+/* psx-interv.c: test POSIX intervals, both basic and extended. */
+
+#include "test.h"
+
+void
+test_intervals ()
+{
+ printf ("\nStarting POSIX interval tests.\n");
+
+ test_should_match = true;
+ /* Valid intervals. */
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "abaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")), "a", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,2}b)*")),
+ "abaab", 0, 5, 2, 5, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0}"), "");
+ test_fastmap (BRACES_TO_OPS ("a{0}"), "", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "", 0, 0, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0}"), "x", 0, 0, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0,}"), "");
+ test_match (BRACES_TO_OPS ("a{0,}"), "a");
+ test_fastmap (BRACES_TO_OPS ("a{0,}"), "a", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "a", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,}"), "xax", 0, 0, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,}"), "aa");
+ test_match (BRACES_TO_OPS ("a{0,0}"), "");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "a");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aa");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aaa");
+ TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "aaa", 0, 3, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{1,3}"), "xaaax", 1, 4, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{0,3}b"), "b");
+ test_match (BRACES_TO_OPS ("a{0,3}b"), "aaab");
+ test_fastmap (BRACES_TO_OPS ("a{0,3}b"), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "b", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS ("a{0,3}b"), "xbx", 1, 2, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{1,3}b"), "ab");
+ test_match (BRACES_TO_OPS ("a{1,3}b"), "aaab");
+ test_match (BRACES_TO_OPS ("ab{1,3}c"), "abbbc");
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "b", 0, 1, -1, -1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "ab", 0, 2, 0, 1, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){0,3}b")), "xabx", 1, 3, 1, 2, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "ab");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaab", 0, 4, 2, 3, -1, -1);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "xaaabx", 1, 5, 3, 4, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "ab", 0, 0);
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){0,3}b")), "aaaab", 0, 5, 4, 4, -1, -1);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "b");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "aaab");
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "ab", 0, 0);
+
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,1}ab")), "aaaab", 0, 5, 0, 3, -1, -1);
+
+ test_match (BRACES_TO_OPS (".{0,3}b"), "b");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "ab");
+
+ test_match (BRACES_TO_OPS ("[a]{0,3}b"), "b");
+ test_match (BRACES_TO_OPS ("[a]{0,3}b"), "aaab");
+ test_fastmap (BRACES_TO_OPS ("[a]{0,3}b"), "ab", 0, 0);
+ test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "bcdb");
+ test_match (BRACES_TO_OPS ("ab{0,3}c"), "abbbc");
+ test_match (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "123d");
+ test_fastmap (BRACES_TO_OPS ("[[:digit:]]{0,3}d"), "0123456789d", 0, 0);
+
+ test_match (BRACES_TO_OPS ("\\*{0,3}a"), "***a");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "aaab");
+ test_match (BRACES_TO_OPS ("a{0,3}a"), "aaa");
+ /* Backtracking. */
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 0);
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{1,})*a")), "a", 0, 1, -1, -1, -1, -1);
+
+ test_fastmap (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 0);
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa");
+ TEST_REGISTERS (BRACES_TO_OPS (PARENS_TO_OPS ("(a{2,})*aa")), "aa", 0, 2, -1, -1, -1, -1);
+
+ test_match (BRACES_TO_OPS ("a{2}*"), "");
+ test_match (BRACES_TO_OPS ("a{2}*"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}*"), "");
+ test_match (BRACES_TO_OPS ("a{1}*"), "a");
+ test_match (BRACES_TO_OPS ("a{1}*"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}"), "a");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}{1}"), "a");
+ test_match (BRACES_TO_OPS ("a{1}{1}{2}"), "aa");
+
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "a");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "aa");
+ test_match (BRACES_TO_OPS ("a{1}{1}*"), "aaa");
+
+ test_match (BRACES_TO_OPS ("a{1}{2}"), "aa");
+ test_match (BRACES_TO_OPS ("a{2}{1}"), "aa");
+
+
+ test_should_match = false;
+
+ test_match (BRACES_TO_OPS ("a{0}"), "a");
+ test_match (BRACES_TO_OPS ("a{0,}"), "b");
+ test_match (BRACES_TO_OPS ("a{1}"), "");
+ test_match (BRACES_TO_OPS ("a{1}"), "aa");
+ test_match (BRACES_TO_OPS ("a{1,}"), "");
+ test_match (BRACES_TO_OPS ("a{1,}"), "b");
+ test_match (BRACES_TO_OPS ("a{0,0}"), "a");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "aa");
+ test_match (BRACES_TO_OPS ("a{0,1}"), "b");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "aaaa");
+ test_match (BRACES_TO_OPS ("a{1,3}"), "b");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a){1,3}b")), "aaaab");
+ test_match (BRACES_TO_OPS (PARENS_TO_OPS ("(a*){1,3}b")), "bb");
+ test_match (BRACES_TO_OPS ("[a]{0,3}"), "aaaa");
+ test_match (BRACES_TO_OPS ("[^a]{0,3}b"), "ab");
+ test_match (BRACES_TO_OPS ("ab{0,3}c"), "abababc");
+ test_match (BRACES_TO_OPS ("[:alpha:]{0,3}d"), "123d");
+ test_match (BRACES_TO_OPS ("\\^{1,3}a"), "a");
+ test_match (BRACES_TO_OPS (".{0,3}b"), "aaaab");
+
+ printf ("\nFinished POSIX interval tests.\n");
+}
diff --git a/gnu/lib/libregex/test/regexcpp.sed b/gnu/lib/libregex/test/regexcpp.sed
new file mode 100644
index 0000000..082c136
--- /dev/null
+++ b/gnu/lib/libregex/test/regexcpp.sed
@@ -0,0 +1,8 @@
+/;..*$/s/;/;\
+/g
+/{ .*$/s/{/{\
+/g
+/ \?[^'] /s/?/?\
+/g
+/ : /s/:/:\
+/g
diff --git a/gnu/lib/libregex/test/syntax.skel b/gnu/lib/libregex/test/syntax.skel
new file mode 100644
index 0000000..a3fbf64
--- /dev/null
+++ b/gnu/lib/libregex/test/syntax.skel
@@ -0,0 +1,74 @@
+/* Print which syntax bits are set. */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "regex.h"
+
+/* It's coincidental that these two are currently the same. */
+#define LONGEST_BIT_NAME "RE_UNMATCHED_RIGHT_PAREN_ORD"
+#define LAST_BIT RE_UNMATCHED_RIGHT_PAREN_ORD
+
+/* Sum of above, when printed. Assigned in main. */
+static unsigned longest;
+
+
+static void
+test_bit (syntax, bit, name)
+ reg_syntax_t syntax;
+ unsigned bit;
+ char *name;
+{
+ char padding[100], test_str[100];
+ int padding_count;
+
+ sprintf (test_str, "%s (%d=0x%x)", name, bit, bit);
+ padding_count = longest - strlen (test_str);
+
+ padding[padding_count] = 0;
+ while (padding_count--)
+ {
+ padding[padding_count] = ' ';
+ }
+
+ printf ("%s%s (%d=0x%x): %c\n",
+ name, padding, bit, bit, syntax & bit ? 'y' : 'n');
+}
+
+
+/* Macro to abbreviate the constant arguments. */
+#define TEST_BIT(bit) test_bit (syntax, bit, #bit)
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ reg_syntax_t syntax;
+ char syntax_str[1000], test_str[100];
+
+ switch (argc)
+ {
+ case 1:
+ printf ("Syntax? ");
+ scanf ("%s", syntax_str);
+ break;
+
+ case 2:
+ strcpy (syntax_str, argv[1]);
+ break;
+
+ default:
+ fprintf (stderr, "Usage: syntax [syntax].\n");
+ exit (1);
+ }
+
+ sscanf (syntax_str, "%i", &syntax);
+
+ /* Figure out the longest name, so we can align the output nicely. */
+ sprintf (test_str, "%s (%d=0x%x)", LONGEST_BIT_NAME, LAST_BIT, LAST_BIT);
+ longest = strlen (test_str);
+
+ /* [[[replace with bit tests]]] */
+
+ return 0;
+}
diff --git a/gnu/lib/libregex/test/test.c b/gnu/lib/libregex/test/test.c
new file mode 100644
index 0000000..74b43b2
--- /dev/null
+++ b/gnu/lib/libregex/test/test.c
@@ -0,0 +1,782 @@
+/* test.c: testing routines for regex.c. */
+
+#include <assert.h>
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+/* Just to be complete, we make both the system V/ANSI and the BSD
+ versions of the string functions available. */
+#if USG || STDC_HEADERS
+#include <string.h>
+#define index strchr
+#define rindex strrchr
+#define bcmp(s1, s2, len) memcmp ((s1), (s2), (len))
+#define bcopy(from, to, len) memcpy ((to), (from), (len))
+#define bzero(s, len) memset ((s), 0, (len))
+#else
+#include <strings.h>
+#define strchr index
+#define strrchr rindex
+#ifndef NEED_MEMORY_H
+#define memcmp(s1, s2, n) bcmp ((s1), (s2), (n))
+#define memcpy(to, from, len) bcopy ((from), (to), (len))
+#endif
+extern char *strtok ();
+extern char *strstr ();
+#endif /* not USG or STDC_HEADERS */
+
+/* SunOS 4.1 declares memchr in <memory.h>, not <string.h>. I don't
+ understand why. */
+#if NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#include "test.h"
+
+#define BYTEWIDTH 8
+
+extern void print_partial_compiled_pattern ();
+extern void print_compiled_pattern ();
+extern void print_double_string ();
+
+/* If nonzero, the results of every test are displayed. */
+boolean verbose = false;
+
+/* If nonzero, don't do register testing. */
+boolean omit_register_tests = true;
+
+/* Says whether the current test should match or fail to match. */
+boolean test_should_match;
+
+
+static void
+set_all_registers (start0, end0, start1, end1,
+ start2, end2, start3, end3,
+ start4, end4, start5, end5,
+ start6, end6, start7, end7,
+ start8, end8, start9, end9, regs)
+
+ int start0; int end0; int start1; int end1;
+ int start2; int end2; int start3; int end3;
+ int start4; int end4; int start5; int end5;
+ int start6; int end6; int start7; int end7;
+ int start8; int end8; int start9; int end9;
+ struct re_registers *regs;
+
+ {
+ unsigned r;
+
+ regs->start[0] = start0; regs->end[0] = end0;
+ regs->start[1] = start1; regs->end[1] = end1;
+ regs->start[2] = start2; regs->end[2] = end2;
+ regs->start[3] = start3; regs->end[3] = end3;
+ regs->start[4] = start4; regs->end[4] = end4;
+ regs->start[5] = start5; regs->end[5] = end5;
+ regs->start[6] = start6; regs->end[6] = end6;
+ regs->start[7] = start7; regs->end[7] = end7;
+ regs->start[8] = start8; regs->end[8] = end8;
+ regs->start[9] = start9; regs->end[9] = end9;
+ for (r = 10; r < regs->num_regs; r++)
+ {
+ regs->start[r] = -1;
+ regs->end[r] = -1;
+ }
+ }
+
+
+
+/* Return the concatenation of S1 and S2. This would be a prime place
+ to use varargs. */
+
+char *
+concat (s1, s2)
+ char *s1;
+ char *s2;
+{
+ char *answer = xmalloc (strlen (s1) + strlen (s2) + 1);
+
+ strcpy (answer, s1);
+ strcat (answer, s2);
+
+ return answer;
+}
+
+
+#define OK_TO_SEARCH (nonconst_buf.fastmap_accurate && (str1 || str2))
+
+/* We ignore the `can_be_null' argument. Should just be removed. */
+
+void
+general_test (pattern_should_be_valid, match_whole_string,
+ pat, str1, str2, start, range, end, correct_fastmap,
+ correct_regs, can_be_null)
+ unsigned pattern_should_be_valid;
+ unsigned match_whole_string;
+ const char *pat;
+ char *str1, *str2;
+ int start, range, end;
+ char *correct_fastmap;
+ struct re_registers *correct_regs;
+ int can_be_null;
+{
+ struct re_pattern_buffer nonconst_buf;
+ struct re_pattern_buffer old_buf;
+ struct re_registers regs;
+ const char *r;
+ char fastmap[1 << BYTEWIDTH];
+ unsigned *regs_correct = NULL;
+ unsigned all_regs_correct = 1;
+ boolean fastmap_internal_error = false;
+ unsigned match = 0;
+ unsigned match_1 = 0;
+ unsigned match_2 = 0;
+ unsigned invalid_pattern = 0;
+ boolean internal_error_1 = false;
+ boolean internal_error_2 = false;
+
+
+ nonconst_buf.allocated = 8;
+ nonconst_buf.buffer = xmalloc (nonconst_buf.allocated);
+ nonconst_buf.fastmap = fastmap;
+ nonconst_buf.translate = 0;
+
+ assert (pat != NULL);
+ r = re_compile_pattern (pat, strlen (pat), &nonconst_buf);
+
+ /* Kludge: if we are doing POSIX testing, we really should have
+ called regcomp, not re_compile_pattern. As it happens, the only
+ way in which it matters is that re_compile_pattern sets the
+ newline/anchor field for matching (part of what happens when
+ REG_NEWLINE is given to regcomp). We have to undo that for POSIX
+ matching. */
+ if (t == posix_basic_test || t == posix_extended_test)
+ nonconst_buf.newline_anchor = 0;
+
+ invalid_pattern = r != NULL;
+
+ if (!r)
+ {
+ int r;
+
+ if (!pattern_should_be_valid)
+ printf ("\nShould have been an invalid pattern but wasn't:\n");
+ else
+ {
+ fastmap_internal_error = (re_compile_fastmap (&nonconst_buf) == -2);
+
+ if (correct_fastmap)
+ nonconst_buf.fastmap_accurate =
+ memcmp (nonconst_buf.fastmap, correct_fastmap, 1 << BYTEWIDTH)
+ == 0;
+
+ if (OK_TO_SEARCH)
+ {
+ old_buf = nonconst_buf;
+ old_buf.buffer = (unsigned char *) xmalloc (nonconst_buf.used);
+ memcpy (old_buf.buffer, nonconst_buf.buffer, nonconst_buf.used);
+
+ /* If only one string is null, call re_match or re_search,
+ which is what the user would probably do. */
+ if (str1 == NULL && str2 != NULL
+ || str2 == NULL && str1 != NULL)
+ {
+ char *the_str = str1 == NULL ? str2 : str1;
+
+ match_1
+ = match_whole_string
+ ? (r = re_match (&nonconst_buf, the_str,
+ strlen (the_str), start, &regs))
+ == strlen (the_str)
+ : (r = re_search (&nonconst_buf,
+ the_str, strlen (the_str),
+ start, range, &regs))
+ >= 0;
+
+ if (r == -2)
+ internal_error_1 = true;
+ }
+ else
+ match_1 = 1;
+
+ /* Also call with re_match_2 or re_search_2, as they might
+ do this. (Also can check calling with either string1
+ or string2 or both null.) */
+ if (match_whole_string)
+ {
+ r = re_match_2 (&nonconst_buf,
+ str1, SAFE_STRLEN (str1),
+ str2, SAFE_STRLEN (str2),
+ start, &regs, end);
+ match_2 = r == SAFE_STRLEN (str1) + SAFE_STRLEN (str2);
+ }
+ else
+ {
+ r = re_search_2 (&nonconst_buf,
+ str1, SAFE_STRLEN (str1),
+ str2, SAFE_STRLEN (str2),
+ start, range, &regs, end);
+ match_2 = r >= 0;
+ }
+
+ if (r == -2)
+ internal_error_2 = true;
+
+ match = match_1 & match_2;
+
+ if (correct_regs)
+ {
+ unsigned reg;
+ if (regs_correct != NULL)
+ free (regs_correct);
+
+ regs_correct
+ = (unsigned *) xmalloc (regs.num_regs * sizeof (unsigned));
+
+ for (reg = 0;
+ reg < regs.num_regs && reg < correct_regs->num_regs;
+ reg++)
+ {
+ regs_correct[reg]
+ = (regs.start[reg] == correct_regs->start[reg]
+ && regs.end[reg] == correct_regs->end[reg])
+#ifdef EMPTY_REGS_CONFUSED
+ /* There is confusion in the standard about
+ the registers in some patterns which can
+ match either the empty string or not match.
+ For example, in `((a*))*' against the empty
+ string, the two registers can either match
+ the empty string (be 0/0), or not match
+ (because of the outer *) (be -1/-1). (Or
+ one can do one and one can do the other.) */
+ || (regs.start[reg] == -1 && regs.end[reg] == -1
+ && correct_regs->start[reg]
+ == correct_regs->end[reg])
+#endif
+ ;
+
+ all_regs_correct &= regs_correct[reg];
+ }
+ }
+ } /* OK_TO_SEARCH */
+ }
+ }
+
+ if (fastmap_internal_error)
+ printf ("\n\nInternal error in re_compile_fastmap:");
+
+ if (internal_error_1)
+ {
+ if (!fastmap_internal_error)
+ printf ("\n");
+
+ printf ("\nInternal error in re_match or re_search:");
+ }
+
+ if (internal_error_2)
+ {
+ if (!internal_error_1)
+ printf ("\n");
+
+ printf ("\nInternal error in re_match_2 or re_search_2:");
+ }
+
+ if ((OK_TO_SEARCH && ((match && !test_should_match)
+ || (!match && test_should_match))
+ || (correct_regs && !all_regs_correct))
+ || !nonconst_buf.fastmap_accurate
+ || invalid_pattern
+ || !pattern_should_be_valid
+ || internal_error_1 || internal_error_2
+ || verbose)
+ {
+ if (OK_TO_SEARCH && match && !test_should_match)
+ {
+ printf ("\n\nMatched but shouldn't have:\n");
+ if (match_1)
+ printf ("The single match/search succeeded.\n");
+
+ if (match_2)
+ printf ("The double match/search succeeded.\n");
+ }
+ else if (OK_TO_SEARCH && !match && test_should_match)
+ {
+ printf ("\n\nDidn't match but should have:\n");
+ if (!match_1)
+ printf ("The single match/search failed.\n");
+
+ if (!match_2)
+ printf ("The double match/search failed.\n");
+ }
+ else if (invalid_pattern && pattern_should_be_valid)
+ printf ("\n\nInvalid pattern (%s):\n", r);
+ else if (!nonconst_buf.fastmap_accurate && pattern_should_be_valid)
+ printf ("\n\nIncorrect fastmap:\n");
+ else if (OK_TO_SEARCH && correct_regs && !all_regs_correct)
+ printf ("\n\nNot all registers were correct:\n");
+ else if (verbose)
+ printf ("\n\nTest was OK:\n");
+
+
+ if ((!(invalid_pattern && !pattern_should_be_valid)) || verbose)
+ printf (" Pattern: `%s'.\n", pat);
+
+ if (pattern_should_be_valid || verbose
+ || internal_error_1 || internal_error_2)
+ {
+ printf(" Strings: ");
+ printf ("`%s' and ", str1 == NULL ? "NULL" : str1);
+ printf ("`%s'.\n", str2 == NULL ? "NULL" : str2);
+
+ if ((OK_TO_SEARCH || verbose || internal_error_1 || internal_error_2)
+ && !invalid_pattern)
+ {
+ if (memcmp (old_buf.buffer, nonconst_buf.buffer,
+ nonconst_buf.used) != 0
+ && !invalid_pattern)
+ {
+ printf(" (%s)\n", r ? r : "Valid regular expression");
+ printf ("\n Compiled pattern before matching: ");
+ print_compiled_pattern (&old_buf);
+ printf ("\n Compiled pattern after matching: ");
+ }
+ else
+ printf ("\n Compiled pattern: ");
+
+ print_compiled_pattern (&nonconst_buf);
+ }
+
+ if (correct_fastmap && (!nonconst_buf.fastmap_accurate || verbose))
+ {
+ printf ("\n The fastmap should have been: ");
+ print_fastmap (correct_fastmap);
+
+ printf ("\n Fastmap: ");
+ print_fastmap (fastmap);
+
+ printf ("\n Compiled pattern before matching: ");
+ print_compiled_pattern (&nonconst_buf);
+ }
+
+ if ((!all_regs_correct || verbose) && correct_regs)
+ {
+ unsigned this_reg;
+ printf ("\n Incorrect registers:");
+
+ for (this_reg = 0; this_reg < regs.num_regs; this_reg++)
+ {
+ if (!regs_correct[this_reg])
+ {
+ printf ("\n Register %d's start was %2d. ", this_reg,
+ regs.start[this_reg]);
+ printf ("\tIt should have been %d.\n",
+ correct_regs->start[this_reg]);
+ printf (" Register %d's end was %2d. ", this_reg,
+ regs.end[this_reg]);
+ printf ("\tIt should have been %d.\n",
+ correct_regs->end[this_reg]);
+ }
+ }
+ }
+ }
+ }
+
+ if (nonconst_buf.buffer != NULL)
+ free (nonconst_buf.buffer);
+
+ if (OK_TO_SEARCH)
+ {
+ free (old_buf.buffer);
+
+ if (correct_regs)
+ free (regs_correct);
+
+ }
+
+ nonconst_buf.buffer = old_buf.buffer = NULL;
+ regs_correct = NULL;
+ regs.start = regs.end = NULL;
+
+} /* general_test */
+
+
+void
+test_search_return (match_start_wanted, pattern, string)
+ int match_start_wanted;
+ const char *pattern;
+ char *string;
+{
+ struct re_pattern_buffer buf;
+ char fastmap[1 << BYTEWIDTH];
+ const char *compile_return;
+ int match_start;
+ static num_times_called = 0;
+
+ num_times_called++;
+ buf.allocated = 1;
+ buf.buffer = xmalloc (buf.allocated);
+
+ assert (pattern != NULL);
+ buf.translate = 0;
+ compile_return = re_compile_pattern (pattern, strlen (pattern), &buf);
+
+ if (compile_return)
+ {
+ printf ("\n\nInvalid pattern in test_match_start:\n");
+ printf ("%s\n", compile_return);
+ }
+ else
+ {
+ buf.fastmap = fastmap;
+ match_start = re_search (&buf, string, strlen (string),
+ 0, strlen (string), 0);
+
+ if (match_start != match_start_wanted)
+ printf ("\nWanted search to start at %d but started at %d.\n",
+ match_start, match_start_wanted);
+ }
+ free (buf.buffer);
+ buf.buffer = NULL;
+}
+
+
+#define SET_FASTMAP() \
+ { \
+ unsigned this_char; \
+ \
+ memset (correct_fastmap, invert, (1 << BYTEWIDTH)); \
+ \
+ for (this_char = 0; this_char < strlen (fastmap_string); this_char++)\
+ correct_fastmap[fastmap_string[this_char]] = !invert; \
+ correct_fastmap['\n'] = match_newline; \
+ }
+
+
+void
+test_fastmap (pat, fastmap_string, invert, match_newline)
+ const char *pat;
+ char *fastmap_string;
+ unsigned invert;
+ unsigned match_newline;
+{
+ char correct_fastmap[(1 << BYTEWIDTH)];
+
+ SET_FASTMAP ();
+ general_test (1, 0, pat, NULL, NULL, -1, 0, -1, correct_fastmap, 0, -1);
+}
+
+
+void
+test_fastmap_search (pat, str, fastmap_string, invert, match_newline,
+ can_be_null, start0, end0)
+ const char *pat;
+ char *str;
+ char *fastmap_string;
+ unsigned invert;
+ unsigned match_newline;
+ int can_be_null;
+ int start0;
+ int end0;
+{
+ char correct_fastmap[(1 << BYTEWIDTH)];
+ struct re_registers correct_regs;
+
+ correct_regs.num_regs = RE_NREGS;
+ correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
+ correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
+
+ set_all_registers (start0, end0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, &correct_regs);
+ SET_FASTMAP ();
+ general_test (1, 0, pat, str, NULL, 0, SAFE_STRLEN (str), SAFE_STRLEN (str),
+ correct_fastmap, &correct_regs, can_be_null);
+
+ free (correct_regs.start);
+ free (correct_regs.end);
+}
+
+
+
+
+void
+test_all_registers (pat, str1, str2,
+ start0, end0, start1, end1,
+ start2, end2, start3, end3,
+ start4, end4, start5, end5,
+ start6, end6, start7, end7,
+ start8, end8, start9, end9)
+ char *pat; char *str1; char *str2;
+ int start0; int end0; int start1; int end1;
+ int start2; int end2; int start3; int end3;
+ int start4; int end4; int start5; int end5;
+ int start6; int end6; int start7; int end7;
+ int start8; int end8; int start9; int end9;
+{
+ struct re_registers correct_regs;
+
+ if (omit_register_tests) return;
+
+ correct_regs.num_regs = RE_NREGS;
+ correct_regs.start = (int *) xmalloc (RE_NREGS * sizeof (int));
+ correct_regs.end = (int *) xmalloc (RE_NREGS * sizeof (int));
+
+ set_all_registers (start0, end0, start1, end1, start2, end2, start3, end3,
+ start4, end4, start5, end5, start6, end6, start7, end7,
+ start8, end8, start9, end9, &correct_regs);
+
+ general_test (1, 0, pat, str1, str2, 0,
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2),
+ NULL, &correct_regs, -1);
+
+ free (correct_regs.start);
+ free (correct_regs.end);
+}
+
+
+void
+invalid_pattern (error_code_expected, pattern)
+ int error_code_expected;
+ char *pattern;
+{
+ regex_t pattern_buffer;
+ int cflags
+ = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
+ || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
+ ? REG_EXTENDED : 0;
+
+ test_compile (0, error_code_expected, pattern, &pattern_buffer, cflags);
+}
+
+
+void
+valid_pattern (pattern)
+ char *pattern;
+{
+ regex_t pattern_buffer;
+ int cflags
+ = re_syntax_options == RE_SYNTAX_POSIX_EXTENDED
+ || re_syntax_options == RE_SYNTAX_POSIX_MINIMAL_EXTENDED
+ ? REG_EXTENDED : 0;
+
+ test_compile (1, 0, pattern, &pattern_buffer, cflags);
+}
+
+
+char *
+delimiters_to_ops (source, left_delimiter, right_delimiter)
+ char *source;
+ char left_delimiter;
+ char right_delimiter;
+{
+ static char *answer = NULL;
+ char *tmp = NULL;
+ boolean double_size = false;
+ unsigned source_char;
+ unsigned answer_char = 0;
+
+ assert (source != NULL);
+
+ switch (left_delimiter)
+ {
+ case '(': if (!(re_syntax_options & RE_NO_BK_PARENS))
+ double_size = true;
+ break;
+ case '{': if (!(re_syntax_options & RE_NO_BK_BRACES))
+ double_size = true;
+ break;
+ default: printf ("Found strange delimiter %c in delimiter_to_ops.\n",
+ left_delimiter);
+ printf ("The source was `%s'\n", source);
+ exit (0);
+ }
+
+ if (answer == source)
+ {
+ tmp = (char *) xmalloc (strlen (source) + 1);
+ strcpy (tmp, source);
+ source = tmp;
+ }
+
+ if (answer)
+ {
+ free (answer);
+ answer = NULL;
+ }
+
+ answer = (char *) xmalloc ((double_size
+ ? strlen (source) << 1
+ : strlen (source))
+ + 1);
+ if (!double_size)
+ strcpy (answer, source);
+ else
+ {
+ for (source_char = 0; source_char < strlen (source); source_char++)
+ {
+ if (source[source_char] == left_delimiter
+ || source[source_char] == right_delimiter)
+ answer[answer_char++] = '\\';
+
+ answer[answer_char++] = source[source_char];
+ }
+ answer[answer_char] = 0;
+ }
+
+ return answer;
+}
+
+
+void
+print_pattern_info (pattern, pattern_buffer_ptr)
+ const char *pattern;
+ regex_t *pattern_buffer_ptr;
+{
+ printf (" Pattern: `%s'.\n", pattern);
+ printf (" Compiled pattern: ");
+ print_compiled_pattern (pattern_buffer_ptr);
+}
+
+
+void
+valid_nonposix_pattern (pattern)
+ char *pattern;
+{
+ struct re_pattern_buffer nonconst_buf;
+
+ nonconst_buf.allocated = 0;
+ nonconst_buf.buffer = NULL;
+ nonconst_buf.translate = NULL;
+
+ assert (pattern != NULL);
+
+ if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
+ {
+ printf ("Couldn't compile the pattern.\n");
+ print_pattern_info (pattern, &nonconst_buf);
+ }
+}
+
+
+void
+compile_and_print_pattern (pattern)
+ char *pattern;
+{
+ struct re_pattern_buffer nonconst_buf;
+
+ nonconst_buf.allocated = 0;
+ nonconst_buf.buffer = NULL;
+
+ if (re_compile_pattern (pattern, strlen (pattern), &nonconst_buf))
+ printf ("Couldn't compile the pattern.\n");
+
+ print_pattern_info (pattern, &nonconst_buf);
+}
+
+
+void
+test_case_fold (pattern, string)
+ const char *pattern;
+ char* string;
+{
+ struct re_pattern_buffer nonconst_buf;
+ const char *ret;
+
+ init_pattern_buffer (&nonconst_buf);
+ nonconst_buf.translate = upcase;
+
+ assert (pattern != NULL);
+ ret = re_compile_pattern (pattern, strlen (pattern), &nonconst_buf);
+
+ if (ret)
+ {
+ printf ("\nShould have been a valid pattern but wasn't.\n");
+ print_pattern_info (pattern, &nonconst_buf);
+ }
+ else
+ {
+ if (test_should_match
+ && re_match (&nonconst_buf, string, strlen (string), 0, 0)
+ != strlen (string))
+ {
+ printf ("Match failed for case fold.\n");
+ printf (" Pattern: `%s'.\n", pattern);
+ printf (" String: `%s'.\n", string == NULL ? "NULL" : string);
+ }
+ }
+}
+
+
+void
+test_match_n_times (n, pattern, string)
+ unsigned n;
+ char* pattern;
+ char* string;
+{
+ struct re_pattern_buffer buf;
+ const char *r;
+ unsigned match = 0;
+ unsigned this_match;
+
+ buf.allocated = 0;
+ buf.buffer = NULL;
+ buf.translate = 0;
+
+ assert (pattern != NULL);
+
+ r = re_compile_pattern (pattern, strlen (pattern), &buf);
+ if (r)
+ {
+ printf ("Didn't compile.\n");
+ printf (" Pattern: %s.\n", pattern);
+ }
+ else
+ {
+ for (this_match = 1; this_match <= n; this_match++)
+ match = (re_match (&buf, string, strlen (string),
+ 0, 0)
+ == strlen (string));
+
+ if (match && !test_should_match)
+ printf ("\n\nMatched but shouldn't have:\n");
+ else if (!match && test_should_match)
+ printf ("\n\nDidn't match but should have:\n");
+
+ if ((match && !test_should_match) || (!match && test_should_match))
+ {
+ printf(" The string to match was: ");
+ if (string)
+ printf ("`%s' and ", string);
+ else
+ printf ("`'");
+
+ printf (" Pattern: %s.\n", pattern);
+ printf (" Compiled pattern: %s.\n", pattern);
+ print_compiled_pattern (&buf);
+ }
+ }
+}
+
+
+void
+test_match_2 (pat, str1, str2)
+ const char *pat;
+ char *str1;
+ char *str2;
+{
+ general_test (1, 1, pat, str1, str2, 0, 1,
+ SAFE_STRLEN (str1) + SAFE_STRLEN (str2), NULL, 0, -1);
+}
+
+void
+test_match (pat, str)
+ const char *pat;
+ char *str;
+{
+ test_match_2 (pat, str, NULL);
+ test_match_2 (pat, NULL, str);
+}
diff --git a/gnu/lib/libregex/test/test.h b/gnu/lib/libregex/test/test.h
new file mode 100644
index 0000000..e367c93
--- /dev/null
+++ b/gnu/lib/libregex/test/test.h
@@ -0,0 +1,141 @@
+/* test.h: for Regex testing. */
+
+#ifndef TEST_H
+#define TEST_H
+
+#include <stdio.h>
+#include <assert.h>
+
+#include <sys/types.h>
+#include "regex.h"
+
+
+/* A strlen that works even on a null pointer. */
+#define SAFE_STRLEN(s) (s == NULL ? 0 : strlen (s))
+
+typedef enum { false = 0, true = 1 } boolean;
+
+extern boolean test_should_match;
+extern boolean omit_register_tests;
+extern void *xmalloc ();
+
+/* Defined in upcase.c. */
+extern char upcase[];
+
+typedef enum
+{
+ all_test,
+ other_test,
+ posix_basic_test,
+ posix_extended_test,
+ posix_interface_test,
+ regress_test
+} test_type;
+
+extern test_type t;
+
+
+#if __STDC__
+
+extern char *concat (char *, char *);
+
+extern void general_test (unsigned pattern_should_be_valid,
+ unsigned match_whole_string,
+ const char *pat, char *str1, char *str2,
+ int start, int range, int end,
+ char *correct_fastmap,
+ struct re_registers *correct_regs, int can_be_null);
+
+
+extern void init_pattern_buffer (regex_t *pattern_buffer_ptr);
+
+extern void test_compile (unsigned valid_pattern, int error_code_expected,
+ const char *pattern, regex_t *pattern_buffer_ptr,
+ int cflags);
+
+extern char *delimiter_to_ops (char *source, char left_delimiter,
+ char right_delimiter);
+
+
+extern void test_search_return (int, const char *, char *);
+
+extern void test_berk_search (const char *pattern, char *string);
+
+extern void test_fastmap (const char *pat, char *fastmap_string, unsigned invert,
+ unsigned match_newline);
+
+extern void test_fastmap_search (const char *pat, char *str, char *fastmap_string,
+ unsigned invert, unsigned match_newline,
+ int can_be_null, int start0, int end0);
+
+extern void test_all_registers (char *pat, char *str1, char *str2,
+ int start0, int end0, int start1, int end1,
+ int start2, int end2, int start3, int end3,
+ int start4, int end4, int start5, int end5,
+ int start6, int end6, int start7, int end7,
+ int start8, int end8, int start9, int end9);
+
+extern void print_pattern_info (const char *pattern, regex_t *pattern_buffer_ptr);
+extern void compile_and_print_pattern (char *pattern);
+
+extern void test_case_fold (const char *pattern, char* string);
+
+extern void test_posix_generic ();
+
+extern void test_grouping ();
+
+extern void invalid_pattern (int error_code_expected, char *pattern);
+extern void valid_nonposix_pattern (char *pattern);
+extern void valid_pattern (char *pattern);
+
+extern void test_match_2 (const char *pat, char *str1, char *str2);
+extern void test_match (const char *pat, char *str);
+
+#endif /* __STDC__ */
+
+
+#define TEST_REGISTERS_2(pat, str1, str2, start0, end0, start1, end1, start2, end2)\
+ if (!omit_register_tests) \
+ test_all_registers (pat, str1, str2, start0, end0, start1, end1, \
+ start2, end2, -1, -1, -1, -1, -1, -1, -1, -1,\
+ -1, -1, -1, -1, -1, -1) \
+
+
+#define TEST_REGISTERS(pat, str, start0, end0, start1, end1, start2, end2) \
+ TEST_REGISTERS_2 (pat, str, NULL, start0, end0, start1, end1, start2, end2)\
+
+#define BRACES_TO_OPS(string) ((char *) delimiters_to_ops (string, '{', '}'))
+#define PARENS_TO_OPS(string) ((char *) delimiters_to_ops (string, '(', ')'))
+
+#define INVALID_PATTERN(pat) \
+ general_test (0, 0, pat, NULL, NULL, -1, 0, -1, NULL, 0, -1)
+
+
+#define MATCH_SELF(p) test_match (p, p)
+
+#define TEST_POSITIONED_MATCH(pat, str, start) \
+ general_test (1, 0, pat, str, NULL, start, 1, SAFE_STRLEN (str), \
+ NULL, 0, -1)
+
+#define TEST_TRUNCATED_MATCH(pat, str, end) \
+ general_test (1, 0, pat, str, NULL, 0, 1, end, NULL, 0, -1)
+
+#define TEST_SEARCH_2(pat, str1, str2, start, range, one_past_end) \
+ general_test (1, 0, pat, str1, str2, start, range, one_past_end, \
+ NULL, 0, -1)
+
+#define TEST_SEARCH(pat, str, start, range) \
+ { \
+ TEST_SEARCH_2 (pat, str, NULL, start, range, SAFE_STRLEN (str)); \
+ TEST_SEARCH_2 (pat, NULL, str, start, range, SAFE_STRLEN (str)); \
+ }
+
+#endif /* TEST_H */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/tregress.c b/gnu/lib/libregex/test/tregress.c
new file mode 100644
index 0000000..b6aa560
--- /dev/null
+++ b/gnu/lib/libregex/test/tregress.c
@@ -0,0 +1,464 @@
+/* tregress.c: reported bugs. The `t' just makes the filename not have
+ a common prefix with `regex.c', so completion works better. */
+
+#include "test.h"
+
+
+boolean pause_at_error = true;
+
+char *
+itoa (i)
+ int i;
+{
+ char *a = xmalloc (21); /* sign + 19 digits (enough for 64 bits) + null */
+
+ sprintf (a, "%d", i);
+ return a;
+}
+
+
+static void
+simple_fail (routine, pat, buf, str, ret)
+ const char *routine;
+ const char *pat;
+ struct re_pattern_buffer *buf;
+ const char *str;
+ char *ret;
+{
+ fprintf (stderr, "Failed %s (return = %s).\n", routine, ret);
+ if (str && *str) fprintf (stderr, " String = %s\n", str);
+ fprintf (stderr, " Pattern = %s\n", pat);
+ print_compiled_pattern (buf);
+
+ if (pause_at_error)
+ {
+ fprintf (stderr, "RET to continue: ");
+ (void) getchar ();
+ }
+}
+
+
+/* Abbreviate the most common calls. */
+
+static void
+simple_compile (pat, buf)
+ const char *pat;
+ struct re_pattern_buffer *buf;
+{
+ const char *ret = re_compile_pattern (pat, strlen (pat), buf);
+
+ if (ret != NULL) simple_fail ("compile", pat, buf, NULL, ret);
+}
+
+
+static void
+simple_fastmap (pat)
+ const char *pat;
+{
+ struct re_pattern_buffer buf;
+ char fastmap[256];
+ int ret;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = NULL;
+ buf.fastmap = fastmap;
+
+ simple_compile (pat, &buf);
+
+ ret = re_compile_fastmap (&buf);
+
+ if (ret != 0) simple_fail ("fastmap compile", pat, &buf, NULL, itoa (ret));
+}
+
+
+#define SIMPLE_MATCH(pat, str) do_match (pat, str, strlen (str))
+#define SIMPLE_NONMATCH(pat, str) do_match (pat, str, -1)
+
+static void
+do_match (pat, str, expected)
+ const char *pat, *str;
+ int expected;
+{
+ int ret;
+ unsigned len;
+ struct re_pattern_buffer buf;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = buf.fastmap = NULL;
+
+ simple_compile (pat, &buf);
+
+ len = strlen (str);
+
+ ret = re_match_2 (&buf, NULL, 0, str, len, 0, NULL, len);
+
+ if (ret != expected) simple_fail ("match", pat, &buf, str, itoa (ret));
+}
+
+
+static void
+simple_search (pat, str, correct_startpos)
+ const char *pat, *str;
+ int correct_startpos;
+{
+ int ret;
+ unsigned len;
+ struct re_pattern_buffer buf;
+
+ buf.allocated = 0;
+ buf.buffer = buf.translate = buf.fastmap = NULL;
+
+ simple_compile (pat, &buf);
+
+ len = strlen (str);
+
+ ret = re_search_2 (&buf, NULL, 0, str, len, 0, len, NULL, len);
+
+ if (ret != correct_startpos)
+ simple_fail ("match", pat, &buf, str, itoa (ret));
+}
+
+/* Past bugs people have reported. */
+
+void
+test_regress ()
+{
+ extern char upcase[];
+ struct re_pattern_buffer buf;
+ unsigned len;
+ struct re_registers regs;
+ int ret;
+ char *fastmap = xmalloc (256);
+
+ buf.translate = NULL;
+ buf.fastmap = NULL;
+ buf.allocated = 0;
+ buf.buffer = NULL;
+
+ printf ("\nStarting regression tests.\n");
+ t = regress_test;
+
+ test_should_match = true;
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* enami@sys.ptg.sony.co.jp 10 Nov 92 15:19:02 JST */
+ buf.translate = upcase;
+ SIMPLE_MATCH ("[A-[]", "A");
+ buf.translate = NULL;
+
+ /* meyering@cs.utexas.edu Nov 6 22:34:41 1992 */
+ simple_search ("\\w+", "a", 0);
+
+ /* jimb@occs.cs.oberlin.edu 10 Sep 92 00:42:33 */
+ buf.translate = upcase;
+ SIMPLE_MATCH ("[\001-\377]", "\001");
+ SIMPLE_MATCH ("[\001-\377]", "a");
+ SIMPLE_MATCH ("[\001-\377]", "\377");
+ buf.translate = NULL;
+
+ /* mike@skinner.cs.uoregon.edu 1 Sep 92 01:45:22 */
+ SIMPLE_MATCH ("^^$", "^");
+
+ /* pclink@qld.tne.oz.au Sep 7 22:42:36 1992 */
+ re_set_syntax (RE_INTERVALS);
+ SIMPLE_MATCH ("^a\\{3\\}$", "aaa");
+ SIMPLE_NONMATCH ("^a\\{3\\}$", "aa");
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* pclink@qld.tne.oz.au, 31 Aug 92. (conjecture) */
+ re_set_syntax (RE_INTERVALS);
+ simple_search ("a\\{1,3\\}b", "aaab", 0);
+ simple_search ("a\\{1,3\\}b", "aaaab", 1);
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* trq@dionysos.thphys.ox.ac.uk, 31 Aug 92. (simplified) */
+ simple_fastmap ("^.*\n[ ]*");
+
+ /* wind!greg@plains.NoDak.edu, 25 Aug 92. (simplified) */
+ re_set_syntax (RE_INTERVALS);
+ SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}", "xN0000");
+ SIMPLE_MATCH ("[a-zA-Z]*.\\{5\\}$", "systemxN0000");
+ SIMPLE_MATCH ("\\([a-zA-Z]*\\).\\{5\\}$", "systemxN0000");
+ re_set_syntax (RE_SYNTAX_EMACS);
+
+ /* jimb, 18 Aug 92. Don't use \000, so `strlen' (in our testing
+ routines) will work. (This still tickles the bug jimb reported.) */
+ SIMPLE_MATCH ("[\001-\377]", "\001");
+ SIMPLE_MATCH ("[\001-\377]", "a");
+ SIMPLE_MATCH ("[\001-\377]", "\377");
+
+ /* jimb, 13 Aug 92. */
+ SIMPLE_MATCH ("[\001-\177]", "\177");
+
+ /* Tests based on bwoelfel's below. */
+ SIMPLE_MATCH ("\\(a\\|ab\\)*", "aab");
+ SIMPLE_MATCH ("\\(a\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a*\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a+\\|ab\\)+", "aab");
+ SIMPLE_MATCH ("\\(a?\\|ab\\)+", "aab");
+
+ /* bwoelfel@widget.seas.upenn.edu, 25 Jul 92. */
+ SIMPLE_MATCH ("^\\([ab]+\\|bc\\)+", "abc");
+
+ /* jla, 3 Jul 92. Core dump in re_search_2. */
+ buf.fastmap = fastmap;
+ buf.translate = upcase;
+#define DATEDUMP_PATTERN " *[0-9]*:"
+ if (re_compile_pattern (DATEDUMP_PATTERN, strlen (DATEDUMP_PATTERN), &buf)
+ != NULL)
+ printf ("date dump compile failed.\n");
+ regs.num_regs = 0;
+ regs.start = regs.end = NULL;
+ if (re_search_2 (&buf, NULL, 0, "Thu Jul 2 18:34:18 1992",
+ 24, 3, 21, &regs, 24) != 10)
+ printf ("date dump search failed.\n");
+ buf.fastmap = 0;
+ buf.translate = 0;
+
+
+ /* rms, 4 Jul 1992. Pattern is much slower in Emacs 19. Fastmap
+ should be only a backslash. */
+#define BEGINEND_PATTERN "\\(\\\\begin\\s *{\\)\\|\\(\\\\end\\s *{\\)"
+ test_fastmap (BEGINEND_PATTERN, "\\", false, 0);
+
+
+ /* kaoru@is.s.u-tokyo.ac.jp, 27 Jun 1992. Code for [a-z] (in regex.c)
+ should translate the whole set. */
+ buf.translate = upcase;
+#define CASE_SET_PATTERN "[ -`]"
+ if (re_compile_pattern (CASE_SET_PATTERN, strlen (CASE_SET_PATTERN), &buf)
+ != NULL)
+ printf ("case set compile failed.\n");
+ if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
+ printf ("case set match failed.\n");
+
+#define CASE_SET_PATTERN2 "[`-|]"
+ if (re_compile_pattern (CASE_SET_PATTERN2, strlen (CASE_SET_PATTERN2), &buf)
+ != NULL)
+ printf ("case set2 compile failed.\n");
+ if (re_match_2 (&buf, "K", 1, "", 0, 0, NULL, 1) != 1)
+ printf ("case set2 match failed.\n");
+
+ buf.translate = NULL;
+
+
+ /* jimb, 27 Jun 92. Problems with gaps in the string. */
+#define GAP_PATTERN "x.*y.*z"
+ if (re_compile_pattern (GAP_PATTERN, strlen (GAP_PATTERN), &buf) != NULL)
+ printf ("gap didn't compile.\n");
+ if (re_match_2 (&buf, "x-", 2, "y-z-", 4, 0, NULL, 6) != 5)
+ printf ("gap match failed.\n");
+
+
+ /* jimb, 19 Jun 92. Since `beginning of word' matches at the
+ beginning of the string, then searching ought to find it there.
+ If `re_compile_fastmap' is not called, then it works ok. */
+ buf.fastmap = fastmap;
+#define BOW_BEG_PATTERN "\\<"
+ if (re_compile_pattern (BOW_BEG_PATTERN, strlen (BOW_BEG_PATTERN), &buf)
+ != NULL)
+ printf ("begword-begstring didn't compile.\n");
+ if (re_search (&buf, "foo", 3, 0, 3, NULL) != 0)
+ printf ("begword-begstring search failed.\n");
+
+ /* Same bug report, different null-matching pattern. */
+#define EMPTY_ANCHOR_PATTERN "^$"
+ if (re_compile_pattern (EMPTY_ANCHOR_PATTERN, strlen (EMPTY_ANCHOR_PATTERN),
+ &buf) != NULL)
+ printf ("empty anchor didn't compile.\n");
+ if (re_search (&buf, "foo\n\nbar", 8, 0, 8, NULL) != 4)
+ printf ("empty anchor search failed.\n");
+
+ /* jimb@occs.cs.oberlin.edu, 21 Apr 92. After we first allocate
+ registers for a particular re_pattern_buffer, we might have to
+ reallocate more registers on subsequent calls -- and we should be
+ reusing the same memory. */
+#define ALLOC_REG_PATTERN "\\(abc\\)"
+ free (buf.fastmap);
+ buf.fastmap = 0;
+ if (re_compile_pattern (ALLOC_REG_PATTERN, strlen (ALLOC_REG_PATTERN), &buf)
+ != NULL)
+ printf ("register allocation didn't compile.\n");
+ if (re_match (&buf, "abc", 3, 0, &regs) != 3)
+ printf ("register allocation didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3)
+ printf ("register allocation reg #1 wrong.\n");
+
+ {
+ int *old_regstart = regs.start;
+ int *old_regend = regs.end;
+
+ if (re_match (&buf, "abc", 3, 0, &regs) != 3)
+ printf ("register reallocation didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3
+ || old_regstart[1] != 0 || old_regend[1] != 3
+ || regs.start != old_regstart || regs.end != old_regend)
+ printf ("register reallocation registers wrong.\n");
+ }
+
+ /* jskudlarek@std.MENTORG.COM, 21 Apr 92 (string-match). */
+#define JSKUD_PATTERN "[^/]+\\(/[^/.]+\\)?/[0-9]+$"
+ if (re_compile_pattern (JSKUD_PATTERN, strlen (JSKUD_PATTERN), &buf) != NULL)
+ printf ("jskud test didn't compile.\n");
+ if (re_search (&buf, "a/1", 3, 0, 3, &regs) != 0)
+ printf ("jskud test didn't match.\n");
+ if (regs.start[1] != -1 || regs.end[1] != -1)
+ printf ("jskud test, reg #1 wrong.\n");
+
+ /* jla's bug (with string-match), 5 Feb 92. */
+ TEST_SEARCH ("\\`[ \t\n]*", "jla@challenger (Joseph Arceneaux)", 0, 100);
+
+ /* jwz@lucid.com, 8 March 1992 (re-search-forward). (His is the
+ second.) These are not supposed to match. */
+#if 0
+ /* This one fails quickly, because we can change the maybe_pop_jump
+ from the + to a pop_failure_pop, because of the c's. */
+ TEST_SEARCH ("^\\(To\\|CC\\):\\([^c]*\\)+co",
+"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
+Cc: eb@thalidomide, jlm@thalidomide\n\
+Subject: Re: so is this really as horrible an idea as it seems to me?\n\
+In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
+References: <9203080736.AA05869@thalidomide.lucid>\n\
+ <9203081900.AA24794@titanic.lucid>", 0, 5000);
+
+ /* This one takes a long, long time to complete, because we have to
+ keep the failure points around because we might backtrack. */
+ TEST_SEARCH ("^\\(To\\|CC\\):\\(.*\n.*\\)+co",
+ /* "X-Windows: The joke that kills.\n\
+FCC: /u/jwz/VM/inbox\n\
+From: Jamie Zawinski <jwz@lucid.com>\n\ */
+"To: hbs%titanic@lucid.com (Harlan Sexton)\n\
+Cc: eb@thalidomide, jlm@thalidomide\n\
+Subject: Re: so is this really as horrible an idea as it seems to me?\n\
+In-Reply-To: Harlan Sexton's message of Sun 8-Mar-92 11:00:06 PST <9203081900.AA24794@titanic.lucid>\n\
+References: <9203080736.AA05869@thalidomide.lucid>\n\
+ <9203081900.AA24794@titanic.lucid>", 0, 5000);
+#endif /* 0 [failed searches] */
+
+
+ /* macrakis' bugs. */
+ buf.translate = upcase; /* message of 24 Jan 91 */
+ if (re_compile_pattern ("[!-`]", 5, &buf) != NULL)
+ printf ("Range test didn't compile.\n");
+ if (re_match (&buf, "A", 1, 0, NULL) != 1)
+ printf ("Range test #1 didn't match.\n");
+ if (re_match (&buf, "a", 1, 0, NULL) != 1)
+ printf ("Range test #2 didn't match.\n");
+
+ buf.translate = 0;
+#define FAO_PATTERN "\\(f\\(.\\)o\\)+"
+ if (re_compile_pattern (FAO_PATTERN, strlen (FAO_PATTERN), &buf) != NULL)
+ printf ("faofdx test didn't compile.\n");
+ if (re_search (&buf, "faofdx", 6, 0, 6, &regs) != 0)
+ printf ("faofdx test didn't match.\n");
+ if (regs.start[1] != 0 || regs.end[1] != 3)
+ printf ("faofdx test, reg #1 wrong.\n");
+ if (regs.start[2] != 1 || regs.end[2] != 2)
+ printf ("faofdx test, reg #2 wrong.\n");
+
+ TEST_REGISTERS ("\\(a\\)*a", "aaa", 0, 3, 1, 2, -1, -1);
+ test_fastmap ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)", " \n", 1, 0);
+
+ /* 40 lines, 48 a's in each line. */
+ test_match ("^\\([^ \n]+:\n\\)+\\([^ \n]+:\\)",
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:\n\
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:");
+
+ /* 640 a's followed by one b, twice. */
+ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab");
+
+ /* 640 a's followed by two b's, twice. */
+ test_match ("\\(.*\\)\\1", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb");
+
+
+ /* Dave G. bug: Reference to a subexpression which didn't match.
+ Should fail. */
+ re_set_syntax (RE_NO_BK_PARENS | RE_NO_BK_VBAR);
+ test_match ("(ooooooooooone())-annnnnnnnnnnd-(twooooooooooo\\2)",
+ "ooooooooooone-annnnnnnnnnnd-twooooooooooo");
+ test_match ("(o|t)", "o");
+ test_match ("(o()|t)", "o");
+ test_match ("(o|t)", "o");
+ test_match ("(ooooooooooooooo|tttttttttttttttt())", "ooooooooooooooo");
+ test_match ("(o|t())", "o");
+ test_match ("(o()|t())", "o");
+ test_match ("(ooooooooooooooooooooooooone()|twooooooooooooooooooooooooo())", "ooooooooooooooooooooooooone");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-t");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-f");
+
+ test_should_match = 0;
+ test_match ("(foo(bar)|second)\\2", "second");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "t-a-t");
+ test_match ("(o()|t())-a-(t\\2|f\\3)", "o-a-f");
+
+ re_set_syntax (RE_SYNTAX_EMACS);
+ test_match ("\\(foo\\(bar\\)\\|second\\)\\2", "secondbar");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "one-and-four");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "two-and-three");
+
+ test_should_match = 1;
+ re_set_syntax (RE_SYNTAX_EMACS);
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "one-and-three");
+ test_match ("\\(one\\(\\)\\|two\\(\\)\\)-and-\\(three\\2\\|four\\3\\)",
+ "two-and-four");
+
+ TEST_REGISTERS (":\\(.*\\)", ":/", 0, 2, 1, 2, -1, -1);
+
+ /* Bug with `upcase' translation table, from Nico Josuttis
+ <nico@bredex.de> */
+ test_should_match = 1;
+ test_case_fold ("[a-a]", "a");
+
+ printf ("\nFinished regression tests.\n");
+}
+
+
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/lib/libregex/test/upcase.c b/gnu/lib/libregex/test/upcase.c
new file mode 100644
index 0000000..a3c0fbc
--- /dev/null
+++ b/gnu/lib/libregex/test/upcase.c
@@ -0,0 +1,39 @@
+/* Indexed by a character, gives the upper case equivalent of the
+ character. */
+
+char upcase[0400] =
+ { 000, 001, 002, 003, 004, 005, 006, 007,
+ 010, 011, 012, 013, 014, 015, 016, 017,
+ 020, 021, 022, 023, 024, 025, 026, 027,
+ 030, 031, 032, 033, 034, 035, 036, 037,
+ 040, 041, 042, 043, 044, 045, 046, 047,
+ 050, 051, 052, 053, 054, 055, 056, 057,
+ 060, 061, 062, 063, 064, 065, 066, 067,
+ 070, 071, 072, 073, 074, 075, 076, 077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+ };
+
+
diff --git a/gnu/lib/libregex/test/xmalloc.c b/gnu/lib/libregex/test/xmalloc.c
new file mode 100644
index 0000000..aa1c6c4
--- /dev/null
+++ b/gnu/lib/libregex/test/xmalloc.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+extern char *malloc ();
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+void *
+xmalloc (size)
+ unsigned size;
+{
+ char *new_mem = malloc (size);
+
+ if (new_mem == NULL)
+ {
+ fprintf (stderr, "xmalloc: request for %u bytes failed.\n", size);
+ abort ();
+ }
+
+ return new_mem;
+}
diff --git a/gnu/lib/libstdc++/Makefile b/gnu/lib/libstdc++/Makefile
new file mode 100644
index 0000000..6ebf71c
--- /dev/null
+++ b/gnu/lib/libstdc++/Makefile
@@ -0,0 +1,286 @@
+#
+# $Id$
+#
+
+GPPDIR= ${.CURDIR}/../../../contrib/libg++
+
+.PATH: ${GPPDIR}/libstdc++ ${GPPDIR}/libio ${GPPDIR}/libiberty
+
+LIB= stdc++
+SHLIB_MAJOR= 2
+SHLIB_MINOR= 0
+CPLUSPLUSLIB= 1 # include c++rt0.o for static constructors
+
+CFLAGS+= -I${GPPDIR}/include -I/usr/include/g++ -I.
+CXXFLAGS+= -I${GPPDIR}/include -I${GPPDIR}/libio -I${GPPDIR}/libstdc++
+CXXFLAGS+= -fno-implicit-templates
+
+DIR= ${GPPDIR}/libstdc++
+
+HDRS= cassert cctype cerrno cfloat ciso646 climits clocale cmath complex \
+ csetjmp csignal cstdarg cstddef cstdio cstdlib cstring ctime \
+ cwchar cwctype new stddef string exception stdexcept typeinfo \
+ algorithm deque list map queue set stack vector utility functional \
+ iterator memory numeric \
+ complex.h new.h stl.h
+
+SHDRS= bastring.cc bastring.h cassert.h cctype.h cerrno.h cfloat.h cinst.h \
+ ciso646.h climits.h clocale.h cmath.h complex.h complext.cc \
+ complext.h csetjmp.h csignal.h cstdarg.h cstddef.h cstdio.h \
+ cstdlib.h cstring.h ctime.h cwchar.h cwctype.h dcomplex.h exception.h \
+ fcomplex.h ldcomplex.h new.h sinst.h stddef.h stdexcept.h straits.h \
+ string.h typeinfo.h
+
+STLHDRS=algo.h algobase.h bool.h bvector.h defalloc.h deque.h faralloc.h \
+ fdeque.h flist.h fmap.h fmultmap.h fmultset.h fset.h function.h \
+ hdeque.h heap.h hlist.h hmap.h hmultmap.h hmultset.h hset.h \
+ hugalloc.h hvector.h iterator.h lbvector.h ldeque.h list.h llist.h \
+ lmap.h lmultmap.h lmultset.h lngalloc.h lset.h map.h multimap.h \
+ multiset.h neralloc.h nmap.h nmultmap.h nmultset.h nset.h pair.h \
+ projectn.h set.h stack.h tempbuf.h tree.h vector.h
+
+SRCS+= newi.cc cstringi.cc stddefi.cc typeinfoi.cc exceptioni.cc \
+ stdexcepti.cc cstdlibi.cc cmathi.cc
+
+# "standard" C parts of libiberty (strerror is a superset of the libc version)
+SRCS+= insque.c strerror.c
+
+# Headers for iostream
+IHDRS= PlotFile.h SFile.h builtinbuf.h editbuf.h floatio.h fstream.h \
+ indstream.h iolibio.h iomanip.h iostdio.h iostream.h iostreamP.h \
+ istream.h libio.h libioP.h ostream.h parsestream.h pfstream.h \
+ procbuf.h stdiostream.h stream.h streambuf.h strfile.h strstream.h
+
+# C++ parts of iostream
+SRCS+= PlotFile.cc SFile.cc builtinbuf.cc editbuf.cc filebuf.cc fstream.cc \
+ indstream.cc ioassign.cc ioextend.cc iomanip.cc iostream.cc \
+ isgetline.cc isgetsb.cc isscan.cc osform.cc parsestream.cc \
+ pfstream.cc procbuf.cc sbform.cc sbgetline.cc sbscan.cc \
+ stdiostream.cc stdstrbufs.cc stdstreams.cc stream.cc streambuf.cc \
+ streambuf.cc strstream.cc
+
+# C parts of iostream
+SRCS+= cleanup.c filedoalloc.c fileops.c floatconv.c genops.c iofclose.c \
+ iofgetpos.c iofread.c iofscanf.c iofsetpos.c iogetdelim.c iogetline.c \
+ ioignore.c iopadn.c iopopen.c ioprims.c ioprintf.c ioseekoff.c \
+ ioseekpos.c iostrerror.c ioungetc.c iovfprintf.c iovfscanf.c \
+ outfloat.c strops.c
+
+beforedepend: config.h
+strerror.o: config.h
+CLEANFILES+= config.h
+
+config.h:
+ touch config.h
+
+beforeinstall:
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${.CURDIR}/_G_config.h \
+ ${HDRS:S;^;${GPPDIR}/libstdc++/;} \
+ ${IHDRS:S;^;${GPPDIR}/libio/;} \
+ ${STLHDRS:S;^;${GPPDIR}/libstdc++/stl/;} \
+ ${DESTDIR}/usr/include/g++
+ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
+ ${SHDRS:S;^;${GPPDIR}/libstdc++/std/;} \
+ ${DESTDIR}/usr/include/g++/std
+
+# Lots of special cases
+
+# ======== typeinfoi.o, stdexcepti.o ========
+.for file in typeinfoi stdexcepti
+${file}.o: ${file}.cc
+ ${CXX} ${CXXFLAGS} -frtti -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${file}.so: ${file}.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} -frtti -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${file}.po: ${file}.cc
+ ${CXX} -p ${CXXFLAGS} -frtti -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+.endfor
+
+# ======== exceptioni.o ========
+.for file in exceptioni
+${file}.o: ${file}.cc
+ ${CXX} ${CXXFLAGS} -O0 -frtti -fhandle-exceptions -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${file}.so: ${file}.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} -O0 -frtti -fhandle-exceptions -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+${file}.po: ${file}.cc
+ ${CXX} -p ${CXXFLAGS} -O0 -frtti -fhandle-exceptions -c ${DIR}/${file}.cc -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+.endfor
+
+# ======== cstrmain.o ========
+CSTRMAIN= -DC
+.for i in REP MAIN TRAITS ADDSS ADDPS ADDCS ADDSP ADDSC EQSS EQPS EQSP NESS \
+ NEPS NESP LTSS LTPS LTSP GTSS GTPS GTSP LESS LEPS LESP GESS GEPS GESP
+CSTRMAIN+= -D${i}
+.endfor
+
+OBJS+= cstrmain.o
+
+cstrmain.o: sinst.cc
+ ${CXX} ${CXXFLAGS} ${CSTRMAIN} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+cstrmain.so: sinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${CSTRMAIN} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+cstrmain.po: sinst.cc
+ ${CXX} -p ${CXXFLAGS} ${CSTRMAIN} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== cstrio.o ========
+CSTRIO= -DC
+.for i in EXTRACT INSERT GETLINE
+CSTRIO+= -D${i}
+.endfor
+
+OBJS+= cstrio.o
+
+cstrio.o: sinst.cc
+ ${CXX} ${CXXFLAGS} ${CSTRIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+cstrio.so: sinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${CSTRIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+cstrio.po: sinst.cc
+ ${CXX} -p ${CXXFLAGS} ${CSTRIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== fcomplex.o =======
+FCOMPLEX= -DF
+.for i in MAIN ADD CC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC \
+ DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR \
+ CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT
+FCOMPLEX+= -D${i}
+.endfor
+
+OBJS+= fcomplex.o
+
+fcomplex.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${FCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+fcomplex.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${FCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+fcomplex.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${FCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== fcomio.o =======
+FCOMIO= -DF
+.for i in EXTRACT INSERT
+FCOMIO+=-D${i}
+.endfor
+
+OBJS+= fcomio.o
+
+fcomio.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${FCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+fcomio.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${FCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+fcomio.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${FCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== dcomplex.o =======
+DCOMPLEX= -DD
+.for i in MAIN ADD CC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC \
+ DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR \
+ CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT
+DCOMPLEX+= -D${i}
+.endfor
+
+OBJS+= dcomplex.o
+
+dcomplex.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${DCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+dcomplex.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${DCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+dcomplex.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${DCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== dcomio.o =======
+DCOMIO= -DD
+.for i in EXTRACT INSERT
+DCOMIO+=-D${i}
+.endfor
+
+OBJS+= dcomio.o
+
+dcomio.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${DCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+dcomio.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${DCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+dcomio.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${DCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== ldcomplex.o =======
+LDCOMPLEX= -DLD
+.for i in MAIN ADD CC ADDCF ADDFC SUBCC SUBCF SUBFC MULCC MULCF MULFC DIVCC \
+ DIVCF DIVFC PLUS MINUS EQCC EQCF EQFC NECC NECF NEFC ABS ARG POLAR \
+ CONJ NORM COS COSH EXP LOG POWCC POWCF POWCI POWFC SIN SINH SQRT
+LDCOMPLEX+= -D${i}
+.endfor
+
+OBJS+= ldcomplex.o
+
+ldcomplex.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${LDCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+ldcomplex.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${LDCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+ldcomplex.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${LDCOMPLEX} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+# ======== ldcomio.o =======
+LDCOMIO= -DLD
+.for i in EXTRACT INSERT
+LDCOMIO+=-D${i}
+.endfor
+
+OBJS+= ldcomio.o
+
+ldcomio.o: cinst.cc
+ ${CXX} ${CXXFLAGS} ${LDCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+ldcomio.so: cinst.cc
+ ${CXX} ${PICFLAG} -DPIC ${CXXFLAGS} ${LDCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -x -r ${.TARGET}
+
+ldcomio.po: cinst.cc
+ ${CXX} -p ${CXXFLAGS} ${LDCOMIO} -c ${.ALLSRC} -o ${.TARGET}
+ @${LD} -O ${.TARGET} -X -r ${.TARGET}
+
+.include <bsd.lib.mk>
diff --git a/gnu/lib/libstdc++/_G_config.h b/gnu/lib/libstdc++/_G_config.h
new file mode 100644
index 0000000..fd67d03
--- /dev/null
+++ b/gnu/lib/libstdc++/_G_config.h
@@ -0,0 +1,78 @@
+/* AUTOMATICALLY GENERATED; DO NOT EDIT! */
+#ifndef _G_config_h
+#define _G_config_h
+#define _G_LIB_VERSION "2.7.2"
+#define _G_NAMES_HAVE_UNDERSCORE 1
+#define _G_VTABLE_LABEL_HAS_LENGTH 1
+#define _G_VTABLE_LABEL_PREFIX "__vt$"
+#define _G_HAVE_ST_BLKSIZE 1
+typedef unsigned long _G_clock_t;
+typedef unsigned int _G_dev_t;
+typedef long long _G_fpos_t;
+typedef unsigned int _G_gid_t;
+typedef unsigned int _G_ino_t;
+typedef unsigned short _G_mode_t;
+typedef unsigned short _G_nlink_t;
+typedef long long _G_off_t;
+typedef int _G_pid_t;
+#ifndef __PTRDIFF_TYPE__
+#define __PTRDIFF_TYPE__ int
+#endif
+typedef __PTRDIFF_TYPE__ _G_ptrdiff_t;
+typedef unsigned int _G_sigset_t;
+#ifndef __SIZE_TYPE__
+#define __SIZE_TYPE__ unsigned int
+#endif
+typedef __SIZE_TYPE__ _G_size_t;
+typedef long _G_time_t;
+typedef unsigned int _G_uid_t;
+typedef int _G_wchar_t;
+typedef int _G_ssize_t;
+typedef int /* default */ _G_wint_t;
+typedef char * _G_va_list;
+#define _G_signal_return_type void
+#define _G_sprintf_return_type int
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+typedef int _G_int8_t __attribute__((__mode__(__QI__)));
+typedef unsigned int _G_uint8_t __attribute__((__mode__(__QI__)));
+typedef int _G_int16_t __attribute__((__mode__(__HI__)));
+typedef unsigned int _G_uint16_t __attribute__((__mode__(__HI__)));
+typedef int _G_int32_t __attribute__((__mode__(__SI__)));
+typedef unsigned int _G_uint32_t __attribute__((__mode__(__SI__)));
+typedef int _G_int64_t __attribute__((__mode__(__DI__)));
+typedef unsigned int _G_uint64_t __attribute__((__mode__(__DI__)));
+#else
+typedef short _G_int16_t;
+typedef unsigned short _G_uint16_t;
+typedef int _G_int32_t;
+typedef unsigned int _G_uint32_t;
+#endif
+
+#define _G_BUFSIZ 1024
+#define _G_FOPEN_MAX 20
+#define _G_FILENAME_MAX 1024
+#define _G_NULL 0 /* default */
+#if defined (__cplusplus) || defined (__STDC__)
+#define _G_ARGS(ARGLIST) ARGLIST
+#else
+#define _G_ARGS(ARGLIST) ()
+#endif
+#if !defined (__GNUG__) || defined (__STRICT_ANSI__)
+#define _G_NO_NRV
+#endif
+#if !defined (__GNUG__)
+#define _G_NO_EXTERN_TEMPLATES
+#endif
+#define _G_HAVE_ATEXIT 1
+#define _G_HAVE_SYS_RESOURCE 1
+#define _G_HAVE_SYS_TIMES 1
+#define _G_HAVE_SYS_SOCKET 1
+#define _G_HAVE_SYS_CDEFS 1
+#define _G_HAVE_SYS_WAIT 1
+#define _G_HAVE_UNISTD 1
+#define _G_HAVE_DIRENT 1
+#define _G_HAVE_CURSES 1
+#define _G_MATH_H_INLINES 0
+#define _G_HAVE_BOOL 1
+#endif /* !_G_config_h */
OpenPOWER on IntegriCloud