--- gcj-4.1-4.1.1.orig/debian/rules.d/binary-cxx-cross.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-cxx-cross.mk @@ -0,0 +1,42 @@ +arch_binaries := $(arch_binaries) cxx + +dirs_cxx = \ + $(docdir) \ + $(PF)/bin \ + $(gcc_lib_dir) \ + $(PF)/share/man/man1 +files_cxx = \ + $(PF)/bin/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver) \ + $(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver).1 \ + $(gcc_lib_dir)/cc1plus + +# ---------------------------------------------------------------------- +$(binary_stamp)-cxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_cxx) + dh_installdirs -p$(p_cxx) $(dirs_cxx) + DH_COMPAT=2 dh_movefiles -p$(p_cxx) $(files_cxx) +# g++ man page is a .so link + rm -f $(d_cxx)/$(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver).1 + ln -sf $(DEB_TARGET_GNU_TYPE)-gcc$(pkg_ver).1.gz \ + $(d_cxx)/$(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver).1.gz + + debian/dh_doclink -p$(p_cxx) $(p_base) + debian/dh_rmemptydirs -p$(p_cxx) + + dh_strip -p$(p_cxx) + dh_compress -p$(p_cxx) + dh_fixperms -p$(p_cxx) + dh_shlibdeps -p$(p_cxx) + dh_gencontrol -p$(p_cxx) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_cxx) + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g;s/gcc/g++/g' < debian/gcc-cross.postinst > debian/$(p_cxx)/DEBIAN/postinst + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g;s/gcc/g++/g' < debian/gcc-cross.prerm > debian/$(p_cxx)/DEBIAN/prerm + chmod 755 debian/$(p_cxx)/DEBIAN/{postinst,prerm} + dh_md5sums -p$(p_cxx) + dh_builddeb -p$(p_cxx) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-fixincl.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-fixincl.mk @@ -0,0 +1,47 @@ +arch_binaries := $(arch_binaries) fixincl + +p_fix = fixincludes +d_fix = debian/$(p_fix) + +dirs_fix = \ + $(docdir)/$(p_base)/fixincludes \ + $(PF)/share/man/man1 \ + $(PF)/bin \ + $(gcc_lexec_dir) \ + $(gcc_lib_dir) +files_fix = \ + $(gcc_lexec_dir)/install-tools \ + $(gcc_lib_dir)/install-tools + +# ---------------------------------------------------------------------- +$(binary_stamp)-fixincl: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_fix) + dh_installdirs -p$(p_fix) $(dirs_fix) + DH_COMPAT=2 dh_movefiles -p$(p_fix) $(files_fix) + +# $(IP) $(builddir)/gcc/fixinc/fixincl $(d_fix)/$(PF)/lib/fixincludes/ +# sed -e "s,^FIXINCL=\(.*\),FIXINCL=/$(PF)/lib/fixincludes/fixincl," \ +# $(builddir)/gcc/fixinc.sh \ +# > $(d_fix)/$(PF)/lib/fixincludes/fixinc.sh +# chmod 755 $(d_fix)/$(PF)/lib/fixincludes/fixinc.sh + $(IR) $(srcdir)/fixincludes/README \ + $(d_fix)/$(docdir)/$(p_base)/fixincludes + sed -e 's,@LIBEXECDIR@,$(gcc_lexec_dir),g' debian/fixincludes.in \ + > $(d_fix)/$(PF)/bin/fixincludes + chmod 755 $(d_fix)/$(PF)/bin/fixincludes + + debian/dh_doclink -p$(p_fix) $(p_base) + dh_strip -p$(p_fix) + dh_compress -p$(p_fix) + dh_fixperms -p$(p_fix) + dh_shlibdeps -p$(p_fix) + dh_gencontrol -p$(p_fix) -- -v$(DEB_EVERSION) $(common_substvars) + dh_installdeb -p$(p_fix) + dh_md5sums -p$(p_fix) + dh_builddeb -p$(p_fix) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-snapshot.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-snapshot.mk @@ -0,0 +1,87 @@ +arch_binaries := $(arch_binaries) snapshot + +p_snap = gcc-snapshot +d_snap = debian/$(p_snap) + +dirs_snap = \ + $(docdir)/$(p_snap) \ + usr/lib +files_snap = + +# ---------------------------------------------------------------------- +$(binary_stamp)-snapshot: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_snap) + dh_installdirs -p$(p_snap) $(dirs_snap) + + -find $(d) -name '*.gch' -type d | xargs rm -rf + + : # dh_movefiles -p$(p_snap) $(files_snap) + rm -f $(d_snap)/$(PF) + mv $(d)/$(PF) $(d_snap)/usr/lib/ + + rm -rf $(d_snap)/$(PF)/lib/nof + +ifeq ($(DEB_TARGET_ARCH),hppa) + rm -f $(install_hppa64_stamp) + + : # provide as and ld links + dh_link -p $(p_snap) \ + /usr/bin/hppa64-linux-gnu-as \ + /$(PF)/lib/gcc/hppa64-linux-gnu/$(GCC_VERSION)/as \ + /usr/bin/hppa64-linux-gnu-ld \ + /$(PF)/lib/gcc/hppa64-linux-gnu/$(GCC_VERSION)/ld + + DH_COMPAT=2 dh_movefiles -p$(p_snap) --sourcedir=$(d_hppa64) \ + $(PF)/libexec \ + $(PF)/lib \ + $(PF)/bin/hppa64-linux-gnu-{cpp,gcc} +endif + +ifeq ($(with_check),yes) + dh_installdocs -p$(p_snap) test-summary + ifeq ($(with_pascal),yes) + cp -p gpc-test-summary $(d_snap)/$(docdir)/$(p_snap)/ + endif +else + dh_installdocs -p$(p_snap) +endif + if [ -f $(buildlibdir)/libstdc++-v3/testsuite/current_symbols.txt ]; \ + then \ + cp -p $(buildlibdir)/libstdc++-v3/testsuite/current_symbols.txt \ + $(d_snap)/$(docdir)/$(p_snap)/libstdc++6_symbols.txt; \ + fi + cp -p debian/README.snapshot \ + $(d_snap)/$(docdir)/$(p_snap)/README.Debian + dh_installchangelogs -p$(p_snap) +ifeq ($(DEB_TARGET_ARCH),hppa) + dh_strip -p$(p_snap) -Xdebug -X.o -X.a +else + dh_strip -p$(p_snap) -Xdebug +endif + dh_compress -p$(p_snap) + -find $(d_snap) -type d ! -perm 755 -exec chmod 755 {} \; + dh_fixperms -p$(p_snap) +ifeq ($(biarch),yes) + mv $(d_snap)/$(PF)/lib64 . +endif +ifeq ($(biarch32),yes) + mv $(d_snap)/$(PF)/lib32 . +endif + dh_shlibdeps -p$(p_snap) \ + -l$(d_snap)/$(PF)/lib:$(d_snap)/$(gcc_lib_dir) +ifeq ($(biarch),yes) + mv lib64 $(d_snap)/$(PF)/ +endif +ifeq ($(biarch32),yes) + mv lib32 $(d_snap)/$(PF)/ +endif + dh_gencontrol -p$(p_snap) -- $(common_substvars) + dh_installdeb -p$(p_snap) + dh_md5sums -p$(p_snap) + dh_builddeb -p$(p_snap) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-softfloat.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-softfloat.mk @@ -0,0 +1,33 @@ +arch_binaries := $(arch_binaries) softfloat + +p_softfloat = gcc$(pkg_ver)-soft-float +d_softfloat = debian/$(p_softfloat) + +dirs_softfloat = \ + $(PF)/$(libdir)/soft-float \ + $(gcc_lib_dir)/soft-float + +files_softfloat = \ + $(PF)/$(libdir)/soft-float \ + $(gcc_lib_dir)/soft-float + +# ---------------------------------------------------------------------- +$(binary_stamp)-softfloat: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_softfloat) + dh_installdirs -p$(p_softfloat) $(dirs_softfloat) + DH_COMPAT=2 dh_movefiles -p$(p_softfloat) $(files_softfloat) + debian/dh_doclink -p$(p_softfloat) $(p_base) + dh_strip -p$(p_softfloat) -Xlibgcj.a + dh_compress -p$(p_softfloat) + dh_fixperms -p$(p_softfloat) + dh_shlibdeps -p$(p_softfloat) + dh_gencontrol -p$(p_softfloat) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_softfloat) + dh_md5sums -p$(p_softfloat) + dh_builddeb -p$(p_softfloat) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-treelang.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-treelang.mk @@ -0,0 +1,55 @@ +arch_binaries := $(arch_binaries) treelang + +p_tree = treelang$(pkg_ver) +d_tree = debian/$(p_tree) + +dirs_tree = \ + $(docdir)/$(p_base)/treelang \ + $(gcc_lexec_dir) \ + $(PF)/bin \ + $(PF)/share/info + +files_tree = \ + $(PF)/bin/gtreelang$(pkg_ver) \ + $(gcc_lexec_dir)/tree1 + +ifneq ($(GFDL_INVARIANT_FREE),yes) + files_tree += \ + $(PF)/share/info/treelang* +endif + +$(binary_stamp)-treelang: $(build_html_stamp) $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_tree) + dh_installdirs -p$(p_tree) $(dirs_tree) + DH_COMPAT=2 dh_movefiles -p$(p_tree) $(files_tree) + + debian/dh_doclink -p$(p_tree) $(p_base) +ifneq ($(GFDL_INVARIANT_FREE),yes) + dh_installdocs -p$(p_tree) + rm -f $(d_tree)/$(docdir)/$(p_base)/copyright + cp -p html/treelang.html $(d_tree)/$(docdir)/$(p_base)/treelang/ +endif + cp -p $(srcdir)/gcc/treelang/README \ + $(d_tree)/$(docdir)/$(p_base)/treelang/. + cp -p $(srcdir)/gcc/treelang/ChangeLog \ + $(d_tree)/$(docdir)/$(p_base)/treelang/changelog + cp -p debian/README.treelang \ + $(d_tree)/$(docdir)/$(p_base)/treelang/README.Debian + + debian/dh_rmemptydirs -p$(p_tree) + + dh_strip -p$(p_tree) + dh_compress -p$(p_tree) + + dh_fixperms -p$(p_tree) + dh_shlibdeps -p$(p_tree) + dh_gencontrol -p$(p_tree) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_tree) + dh_md5sums -p$(p_tree) + dh_builddeb -p$(p_tree) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-hppa64.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-hppa64.mk @@ -0,0 +1,29 @@ +arch_binaries := $(arch_binaries) hppa64 + +# ---------------------------------------------------------------------- +$(binary_stamp)-hppa64: $(install_hppa64_stamp) + dh_testdir + dh_testroot + +# dh_installdirs -p$(p_hppa64) + + : # provide as and ld links + dh_link -p $(p_hppa64) \ + /usr/bin/hppa64-linux-gnu-as \ + /$(PF)/lib/gcc/hppa64-linux-gnu/$(GCC_VERSION)/as \ + /usr/bin/hppa64-linux-gnu-ld \ + /$(PF)/lib/gcc/hppa64-linux-gnu/$(GCC_VERSION)/ld + + debian/dh_doclink -p$(p_hppa64) $(p_base) + debian/dh_rmemptydirs -p$(p_hppa64) + + dh_strip -p$(p_hppa64) -X.o -Xlibgcc.a -Xlibgcov.a + dh_compress -p$(p_hppa64) + dh_fixperms -p$(p_hppa64) + dh_shlibdeps -p$(p_hppa64) + dh_gencontrol -p$(p_hppa64) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_hppa64) + dh_md5sums -p$(p_hppa64) + dh_builddeb -p$(p_hppa64) + + touch $@ --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-cxx.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-cxx.mk @@ -0,0 +1,52 @@ +arch_binaries := $(arch_binaries) cxx + +dirs_cxx = \ + $(docdir)/$(p_base)/C++ \ + $(PF)/bin \ + $(PF)/share/info \ + $(gcc_lexec_dir) \ + $(PF)/share/man/man1 +files_cxx = \ + $(PF)/bin/g++$(pkg_ver) \ + $(PF)/share/man/man1/g++$(pkg_ver).1 \ + $(gcc_lexec_dir)/cc1plus + +# ---------------------------------------------------------------------- +$(binary_stamp)-cxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_cxx) + dh_installdirs -p$(p_cxx) $(dirs_cxx) + DH_COMPAT=2 dh_movefiles -p$(p_cxx) $(files_cxx) +# g++ man page is a .so link + rm -f $(d_cxx)/$(PF)/share/man/man1/g++$(pkg_ver).1 + ln -sf gcc$(pkg_ver).1.gz \ + $(d_cxx)/$(PF)/share/man/man1/g++$(pkg_ver).1.gz + + ln -sf g++$(pkg_ver) \ + $(d_cxx)/$(PF)/bin/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver) + ln -sf g++$(pkg_ver).1.gz \ + $(d_cxx)/$(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-g++$(pkg_ver).1.gz + ln -sf g++$(pkg_ver) \ + $(d_cxx)/$(PF)/bin/$(TARGET_ALIAS)-g++$(pkg_ver) + ln -sf g++$(pkg_ver).1.gz \ + $(d_cxx)/$(PF)/share/man/man1/$(TARGET_ALIAS)-g++$(pkg_ver).1.gz + + debian/dh_doclink -p$(p_cxx) $(p_base) + cp -p debian/README.C++ $(d_cxx)/$(docdir)/$(p_base)/C++/ + cp -p $(srcdir)/gcc/cp/ChangeLog \ + $(d_cxx)/$(docdir)/$(p_base)/C++/changelog + debian/dh_rmemptydirs -p$(p_cxx) + + dh_strip -p$(p_cxx) + dh_compress -p$(p_cxx) + dh_fixperms -p$(p_cxx) + dh_shlibdeps -p$(p_cxx) + dh_gencontrol -p$(p_cxx) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_cxx) + dh_md5sums -p$(p_cxx) + dh_builddeb -p$(p_cxx) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-pascal.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-pascal.mk @@ -0,0 +1,100 @@ +arch_binaries := $(arch_binaries) pascal +indep_binaries := $(indep_binaries) pascal-doc + +p_gpc = gpc$(gpc_pkg_ver) +p_gpcd = gpc$(gpc_pkg_ver)-doc + +d_gpc = debian/$(p_gpc) +d_gpcd = debian/$(p_gpcd) + +dirs_gpc = \ + $(docdir)/$(p_base)/pascal \ + $(PF)/bin \ + $(gcc_lexec_dir) \ + $(gcc_lib_dir)/{include,units} \ + $(PF)/share/man/man1 +ifeq ($(with_gpidump),yes) + files_gpc = \ + $(PF)/bin/{binobj,gpc,gpc-run,gpidump}$(gpc_pkg_ver) \ + $(PF)/share/man/man1/{binobj,gpc,gpc-run,gpidump}$(gpc_pkg_ver).1 \ + $(gcc_lexec_dir)/gpc1 \ + $(gcc_lib_dir)/{libgpc.a,units} \ + $(gcc_lib_dir)/include/gpc-in-c.h +else + files_gpc = \ + $(PF)/bin/{binobj,gpc,gpc-run}$(gpc_pkg_ver) \ + $(PF)/share/man/man1/{binobj,gpc,gpc-run}$(gpc_pkg_ver).1 \ + $(gcc_lexec_dir)/gpc1 \ + $(gcc_lib_dir)/{libgpc.a,units} \ + $(gcc_lib_dir)/include/gpc-in-c.h +endif + +# ---------------------------------------------------------------------- +$(binary_stamp)-pascal: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_gpc) + dh_installdirs -p$(p_gpc) $(dirs_gpc) + + rm -f $(d)/$(PF)/bin/pc $(d)/$(PF)/share/man/man1/pc.1 + DH_COMPAT=2 dh_movefiles -p$(p_gpc) $(files_gpc) + + debian/dh_doclink -p$(p_gpc) $(p_base) + cp -p $(srcdir)/gcc/p/{AUTHORS,FAQ,NEWS,README} \ + $(d_gpc)/$(docdir)/$(p_base)/pascal/. + cp -p $(srcdir)/gcc/p/test/README \ + $(d_gpc)/$(docdir)/$(p_base)/pascal/README.gpc-test + cp -p $(srcdir)/gcc/p/ChangeLog \ + $(d_gpc)/$(docdir)/$(p_base)/pascal/changelog + +# ln -sf ../$(p_gpc)/examples $(d_gpcd)/$(docdir)/$(p_gpcd)/examples +# ln -sf ../$(p_gpc)/docdemos $(d_gpcd)/$(docdir)/$(p_gpcd)/docdemos + + dh_strip -p$(p_gpc) + dh_compress -p$(p_gpc) + dh_fixperms -p$(p_gpc) + dh_shlibdeps -p$(p_gpc) + dh_gencontrol -p$(p_gpc) -- -v$(DEB_GPC_VERSION) $(common_substvars) + dh_installdeb -p$(p_gpc) + dh_md5sums -p$(p_gpc) + dh_builddeb -p$(p_gpc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-pascal-doc: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_gpcd) + dh_installdirs -p$(p_gpcd) \ + $(docdir)/$(p_base)/pascal \ + $(PF)/share/info + DH_COMPAT=2 dh_movefiles -p$(p_gpcd) \ + $(PF)/share/info/gpc*$(gpc_pkg_ver)*info* + debian/dh_doclink -p$(p_gpcd) $(p_base) + dh_installdocs -p$(p_gpcd) + rm -f $(d_gpcd)/$(docdir)/$(p_base)/copyright + cp -p html/gpc.html html/gpcs.html \ + $(d_gpcd)/$(docdir)/$(p_base)/pascal/ + mv $(d)/$(PF)/doc/gpc/demos \ + $(d_gpcd)/$(docdir)/$(p_base)/pascal/examples + mv $(d)/$(PF)/doc/gpc/docdemos \ + $(d_gpcd)/$(docdir)/$(p_base)/pascal/. + +# -$(MAKE) -C $(builddir)/gcc gpc.ps +# cp -p $(builddir)/gcc/gpc.ps $(d_gpcd)/$(docdir)/$(p_base)/pascal/. + + debian/dh_rmemptydirs -p$(p_gpcd) + + dh_compress -p$(p_gpcd) + dh_fixperms -p$(p_gpcd) + dh_installdeb -p$(p_gpcd) + dh_gencontrol -p$(p_gpcd) -- -v$(DEB_GPC_VERSION) $(common_substvars) + dh_md5sums -p$(p_gpcd) + dh_builddeb -p$(p_gpcd) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-proto.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-proto.mk @@ -0,0 +1,43 @@ +arch_binaries := $(arch_binaries) proto + +p_proto = protoize +d_proto = debian/$(p_proto) + +dirs_proto = \ + $(docdir) \ + $(PF)/share/man/man1 \ + $(PF)/bin +files_proto = \ + $(PF)/bin/{protoize,unprotoize} \ + $(PF)/share/man/man1/{protoize,unprotoize}.1 + +# ---------------------------------------------------------------------- +$(binary_stamp)-proto: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_proto) + dh_installdirs -p$(p_proto) $(dirs_proto) + +ifeq ($(versioned_packages),yes) + : # rename versioned files back to unversioned ones. + for i in protoize unprotoize; do \ + mv $(d)/$(PF)/bin/$$i$(pkg_ver) $(d)/$(PF)/bin/$$i; \ + done +endif + $(IR) debian/protoize.1 $(d)/$(PF)/share/man/man1/ + ln -sf protoize.1 $(d)/$(PF)/share/man/man1/unprotoize.1 + DH_COMPAT=2 dh_movefiles -p$(p_proto) $(files_proto) + + debian/dh_doclink -p$(p_proto) $(p_base) + dh_strip -p$(p_proto) + dh_compress -p$(p_proto) + dh_fixperms -p$(p_proto) + dh_shlibdeps -p$(p_proto) + dh_gencontrol -p$(p_proto) -- -v$(DEB_EVERSION) $(common_substvars) + dh_installdeb -p$(p_proto) + dh_md5sums -p$(p_proto) + dh_builddeb -p$(p_proto) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-cpp-cross.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-cpp-cross.mk @@ -0,0 +1,40 @@ +arch_binaries := $(arch_binaries) cpp + +dirs_cpp = \ + $(docdir) \ + $(PF)/share/man/man1 \ + $(PF)/bin \ + $(gcc_lexec_dir) + +files_cpp = \ + $(PF)/bin/$(DEB_TARGET_GNU_TYPE)-cpp$(pkg_ver) \ + $(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-cpp$(pkg_ver).1 \ + $(gcc_lexec_dir)/cc1 + +# ---------------------------------------------------------------------- +$(binary_stamp)-cpp: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_cpp) + dh_installdirs -p$(p_cpp) $(dirs_cpp) + DH_COMPAT=2 dh_movefiles -p$(p_cpp) $(files_cpp) + + debian/dh_doclink -p$(p_cpp) $(p_base) + debian/dh_rmemptydirs -p$(p_cpp) + + dh_strip -p$(p_cpp) + dh_compress -p$(p_cpp) + dh_fixperms -p$(p_cpp) + dh_shlibdeps -p$(p_cpp) + dh_gencontrol -p$(p_cpp) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_cpp) + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g;s/gcc/cpp/g' < debian/gcc-cross.postinst > debian/$(p_cpp)/DEBIAN/postinst + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g;s/gcc/cpp/g' < debian/gcc-cross.prerm > debian/$(p_cpp)/DEBIAN/prerm + chmod 755 debian/$(p_cpp)/DEBIAN/{postinst,prerm} + dh_md5sums -p$(p_cpp) + dh_builddeb -p$(p_cpp) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-nof-cross.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-nof-cross.mk @@ -0,0 +1,46 @@ +arch_binaries := $(arch_binaries) nof + +p_nof = gcc$(pkg_arch)-nof +d_nof = debian/$(p_nof) + +dirs_nof = \ + $(docdir) \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib/nof +ifeq ($(with_cdev),yes) + dirs_nof += \ + $(gcc_lib_dir)/nof +endif + +ifeq ($(with_cdev),yes) + files_nof = \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib/libgcc_s_nof.so.$(GCC_SONAME) \ + $(gcc_lib_dir)/libgcc_s_nof.so \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib/nof \ + $(gcc_lib_dir)/nof +else + files_nof = \ + lib/libgcc_s_nof.so.$(GCC_SONAME) +endif + +# ---------------------------------------------------------------------- +$(binary_stamp)-nof: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + ln -sf /$(PF)/$(DEB_TARGET_GNU_TYPE)/lib/libgcc_s_nof.so.$(GCC_SONAME) \ + $(d)/$(gcc_lib_dir)/libgcc_s_nof.so + + rm -rf $(d_nof) + dh_installdirs -p$(p_nof) $(dirs_nof) + DH_COMPAT=2 dh_movefiles -p$(p_nof) $(files_nof) + debian/dh_doclink -p$(p_nof) $(p_base) + dh_strip -p$(p_nof) + dh_compress -p$(p_nof) + dh_fixperms -p$(p_nof) + dh_gencontrol -p$(p_nof) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_nof) + dh_md5sums -p$(p_nof) + dh_builddeb -p$(p_nof) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-cpp.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-cpp.mk @@ -0,0 +1,73 @@ +arch_binaries := $(arch_binaries) cpp +indep_binaries := $(indep_binaries) cpp-doc + +dirs_cpp = \ + $(docdir) \ + $(PF)/share/man/man1 \ + $(PF)/bin \ + $(gcc_lexec_dir) + +files_cpp = \ + $(PF)/bin/cpp$(pkg_ver) \ + $(PF)/share/man/man1/cpp$(pkg_ver).1 \ + $(gcc_lexec_dir)/cc1 + +# ---------------------------------------------------------------------- +$(binary_stamp)-cpp: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_cpp) + dh_installdirs -p$(p_cpp) $(dirs_cpp) + DH_COMPAT=2 dh_movefiles -p$(p_cpp) $(files_cpp) + + ln -sf cpp$(pkg_ver) \ + $(d_cpp)/$(PF)/bin/$(DEB_TARGET_GNU_TYPE)-cpp$(pkg_ver) + ln -sf cpp$(pkg_ver).1 \ + $(d_cpp)/$(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-cpp$(pkg_ver).1 + ln -sf cpp$(pkg_ver) \ + $(d_cpp)/$(PF)/bin/$(TARGET_ALIAS)-cpp$(pkg_ver) + ln -sf cpp$(pkg_ver).1 \ + $(d_cpp)/$(PF)/share/man/man1/$(TARGET_ALIAS)-cpp$(pkg_ver).1 + + debian/dh_doclink -p$(p_cpp) $(p_base) + debian/dh_rmemptydirs -p$(p_cpp) + + dh_strip -p$(p_cpp) + dh_compress -p$(p_cpp) + dh_fixperms -p$(p_cpp) + dh_shlibdeps -p$(p_cpp) + dh_gencontrol -p$(p_cpp) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_cpp) + dh_md5sums -p$(p_cpp) + dh_builddeb -p$(p_cpp) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-cpp-doc: $(build_html_stamp) $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_cppd) + dh_installdirs -p$(p_cppd) \ + $(docdir)/$(p_base) \ + $(PF)/share/info + DH_COMPAT=2 dh_movefiles -p$(p_cppd) \ + $(PF)/share/info/cpp* + + debian/dh_doclink -p$(p_cppd) $(p_base) + dh_installdocs -p$(p_cppd) html/cpp.html html/cppinternals.html + rm -f $(d_cppd)/$(docdir)/$(p_base)/copyright + debian/dh_rmemptydirs -p$(p_cppd) + + dh_compress -p$(p_cppd) + dh_fixperms -p$(p_cppd) + dh_installdeb -p$(p_cppd) + dh_gencontrol -p$(p_cppd) -- -v$(DEB_VERSION) $(common_substvars) + dh_md5sums -p$(p_cppd) + dh_builddeb -p$(p_cppd) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-nof.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-nof.mk @@ -0,0 +1,56 @@ +arch_binaries := $(arch_binaries) nof + +p_nof = gcc$(pkg_ver)-nof +d_nof = debian/$(p_nof) + +dirs_nof = \ + $(docdir) \ + $(PF)/$(libdir)/nof +ifeq ($(with_cdev),yes) + dirs_nof += \ + $(gcc_lib_dir)/nof +endif + +ifeq ($(with_cdev),yes) + files_nof = \ + $(libdir)/libgcc_s_nof.so.$(GCC_SONAME) \ + $(gcc_lib_dir)/libgcc_s_nof.so \ + $(PF)/$(libdir)/nof \ + $(gcc_lib_dir)/nof +else + files_nof = \ + $(libdir)/libgcc_s_nof.so.$(GCC_SONAME) +endif + +# ---------------------------------------------------------------------- +$(binary_stamp)-nof: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + mv $(d)/$(PF)/$(libdir)/libgcc_s_nof.so.$(GCC_SONAME) $(d)/$(libdir)/. + rm -f $(d)/$(PF)/$(libdir)/libgcc_s_nof.so + ln -sf /$(libdir)/libgcc_s_nof.so.$(GCC_SONAME) \ + $(d)/$(gcc_lib_dir)/libgcc_s_nof.so + + rm -rf $(d_nof) + dh_installdirs -p$(p_nof) $(dirs_nof) + DH_COMPAT=2 dh_movefiles -p$(p_nof) $(files_nof) + debian/dh_doclink -p$(p_nof) $(p_base) + dh_strip -p$(p_nof) + dh_compress -p$(p_nof) + dh_fixperms -p$(p_nof) + dh_shlibdeps -p$(p_nof) + + dh_makeshlibs -p$(p_nof) + : # Only keep the shlibs file for the libgcc_s_nof library + fgrep libgcc_s_nof debian/$(p_nof)/DEBIAN/shlibs \ + > debian/$(p_nof)/DEBIAN/shlibs.tmp + mv -f debian/$(p_nof)/DEBIAN/shlibs.tmp debian/$(p_nof)/DEBIAN/shlibs + + dh_gencontrol -p$(p_nof) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_nof) + dh_md5sums -p$(p_nof) + dh_builddeb -p$(p_nof) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-objcxx.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-objcxx.mk @@ -0,0 +1,38 @@ +arch_binaries := $(arch_binaries) objcxx + +p_objcx = gobjc++$(pkg_ver) +d_objcx = debian/$(p_objcx) + +dirs_objcx = \ + $(docdir)/$(p_base)/Obj-C++ \ + $(gcc_lexec_dir) + +files_objcx = \ + $(gcc_lexec_dir)/cc1objplus + +$(binary_stamp)-objcxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_objcx) + dh_installdirs -p$(p_objcx) $(dirs_objcx) + DH_COMPAT=2 dh_movefiles -p$(p_objcx) $(files_objcx) + + debian/dh_doclink -p$(p_objcx) $(p_base) + cp -p $(srcdir)/gcc/objcp/ChangeLog \ + $(d_objcx)/$(docdir)/$(p_base)/Obj-C++/changelog + + debian/dh_rmemptydirs -p$(p_objcx) + + dh_strip -p$(p_objcx) + dh_compress -p$(p_objcx) + + dh_fixperms -p$(p_objcx) + dh_shlibdeps -p$(p_objcx) + dh_gencontrol -p$(p_objcx) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_objcx) + dh_md5sums -p$(p_objcx) + dh_builddeb -p$(p_objcx) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libobjc.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libobjc.mk @@ -0,0 +1,122 @@ +ifeq ($(with_objcdev),yes) + arch_binaries := $(arch_binaries) libobjc +endif +ifeq ($(with_lib64objc),yes) + arch_binaries := $(arch_binaries) lib64objc +endif +ifeq ($(with_lib32objc),yes) + arch_binaries := $(arch_binaries) lib32objc +endif + +p_lobjc = libobjc$(OBJC_SONAME) +p_l32objc = lib32objc$(OBJC_SONAME) +p_l64objc = lib64objc$(OBJC_SONAME) + +d_lobjc = debian/$(p_lobjc) +d_l32objc = debian/$(p_l32objc) +d_l64objc = debian/$(p_l64objc) + +dirs_lobjc = \ + $(docdir)/objc \ + $(PF)/$(libdir) +files_lobjc = \ + $(PF)/$(libdir)/libobjc.so.* +ifeq ($(with_objc_gc),yes) + files_lobjc += \ + $(PF)/$(libdir)/libobjc_gc.so.* +endif + + +$(binary_stamp)-libobjc: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lobjc) + dh_installdirs -p$(p_lobjc) $(dirs_lobjc) +# mv $(d)/$(gcc_lib_dir)/libobjc.so.* $(d)/$(PF)/$(libdir)/. +#ifeq ($(with_objc_gc),yes) +# mv $(d)/$(gcc_lib_dir)/libobjc_gc.so.* $(d)/$(PF)/$(libdir)/. +#endif + DH_COMPAT=2 dh_movefiles -p$(p_lobjc) $(files_lobjc) + + dh_installdocs -p$(p_lobjc) + echo "See /$(docdir)/$(p_base) for more information" \ + > $(d_lobjc)/$(docdir)/$(p_lobjc)/README.Debian + dh_installchangelogs -p$(p_lobjc) $(srcdir)/libobjc/ChangeLog + + debian/dh_rmemptydirs -p$(p_lobjc) + + dh_strip -p$(p_lobjc) + dh_compress -p$(p_lobjc) + + dh_fixperms -p$(p_lobjc) + b=libobjc; \ + for ext in preinst postinst prerm postrm; do \ + for t in '' -dev -dbg; do \ + v=$(OBJC_SONAME); \ + if [ -f debian/$$b$$t.$$ext ]; then \ + cp -pf debian/$$b$$t.$$ext debian/$$b$$v$$t.$$ext; \ + fi; \ + done; \ + done + dh_makeshlibs -p$(p_lobjc) -V '$(p_lobjc) (>= $(DEB_SOEVERSION))' + dh_shlibdeps -p$(p_lobjc) + dh_gencontrol -p$(p_lobjc) -- -v$(DEB_EVERSION) $(common_substvars) + dh_installdeb -p$(p_lobjc) + dh_md5sums -p$(p_lobjc) + dh_builddeb -p$(p_lobjc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64objc: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l64objc) + dh_installdirs -p$(p_l64objc) \ + $(PF)/lib64 + DH_COMPAT=2 dh_movefiles -p$(p_l64objc) \ + $(PF)/lib64/libobjc.so.* + + debian/dh_doclink -p$(p_l64objc) $(p_base) + + dh_strip -p$(p_l64objc) + dh_compress -p$(p_l64objc) + dh_fixperms -p$(p_l64objc) + dh_makeshlibs -p$(p_l64objc) -V '$(p_l64objc) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l64objc) + dh_gencontrol -p$(p_l64objc) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l64objc) + dh_md5sums -p$(p_l64objc) + dh_builddeb -p$(p_l64objc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32objc: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l32objc) + dh_installdirs -p$(p_l32objc) \ + $(lib32) + DH_COMPAT=2 dh_movefiles -p$(p_l32objc) \ + $(lib32)/libobjc.so.* + + debian/dh_doclink -p$(p_l32objc) $(p_base) + + dh_strip -p$(p_l32objc) + dh_compress -p$(p_l32objc) + dh_fixperms -p$(p_l32objc) + dh_makeshlibs -p$(p_l32objc) -V '$(p_l32objc) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l32objc) + dh_gencontrol -p$(p_l32objc) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l32objc) + dh_md5sums -p$(p_l32objc) + dh_builddeb -p$(p_l32objc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-fastjar.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-fastjar.mk @@ -0,0 +1,55 @@ +arch_binaries := $(arch_binaries) fastjar + +p_fjar = fastjar +d_fjar = debian/$(p_fjar) + +dirs_fjar = \ + $(docdir)/$(p_fjar) \ + $(PF)/bin \ + $(PF)/share/man/man1 \ + $(PF)/share/info + +files_fjar = \ + $(PF)/bin/{fastjar,grepjar}* \ + $(PF)/share/man/man1/{fastjar,grepjar}*.1 \ + $(PF)/share/info/fastjar.info + +# ---------------------------------------------------------------------- +$(binary_stamp)-fastjar: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_fjar) + dh_installdirs -p$(p_fjar) $(dirs_fjar) + +#ifeq ($(versioned_packages),yes) +# : # rename versioned files back to unversioned ones. +# for i in fastjar grepjar; do \ +# mv $(d)/$(PF)/bin/$$i$(pkg_ver) $(d)/$(PF)/bin/$$i; \ +# mv $(d)/$(PF)/share/man/man1/$$i$(pkg_ver).1 \ +# $(d)/$(PF)/share/man/man1/$$i.1; \ +# done +#endif + for i in fastjar grepjar; do \ + ln -s $$i$(pkg_ver) $(d)/$(PF)/bin/$$i; \ + ln -s $$i$(pkg_ver).1 $(d)/$(PF)/share/man/man1/$$i.1; \ + done + + DH_COMPAT=2 dh_movefiles -p$(p_fjar) $(files_fjar) + + dh_installdocs -p$(p_fjar) $(srcdir)/fastjar/{CHANGES,NEWS,README} + dh_installchangelogs -p$(p_fjar) $(srcdir)/fastjar/ChangeLog + + debian/dh_rmemptydirs -p$(p_fjar) + + dh_strip -p$(p_fjar) + dh_compress -p$(p_fjar) + dh_fixperms -p$(p_fjar) + dh_shlibdeps -p$(p_fjar) + dh_gencontrol -p$(p_fjar) -- -v$(DEB_EVERSION) $(common_substvars) + dh_installdeb -p$(p_fjar) + dh_md5sums -p$(p_fjar) + dh_builddeb -p$(p_fjar) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libgcc-cross.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libgcc-cross.mk @@ -0,0 +1,158 @@ +ifeq ($(with_libgcc),yes) + arch_binaries := $(arch_binaries) libgcc +endif +ifeq ($(with_lib64gcc),yes) + arch_binaries := $(arch_binaries) lib64gcc +endif +ifeq ($(biarch32),yes) + arch_binaries := $(arch_binaries) lib32gcc +endif + +p_lgcc = libgcc$(GCC_SONAME)$(cross_lib_arch) +d_lgcc = debian/$(p_lgcc) + +p_l64gcc = lib32gcc$(GCC_SONAME)$(cross_lib_arch) +d_l64gcc = debian/$(p_l32gcc) + +p_l64gcc = lib64gcc$(GCC_SONAME)$(cross_lib_arch) +d_l64gcc = debian/$(p_l64gcc) + +# ---------------------------------------------------------------------- +$(binary_stamp)-libgcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lgcc) + dh_installdirs -p$(p_lgcc) \ + $(docdir)/$(p_lgcc) \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib + +ifeq ($(with_shared_libgcc),yes) + mv $(d)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib/libgcc_s.so.$(GCC_SONAME) $(d_lgcc)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib/. +endif + + dh_installdocs -p$(p_lgcc) + dh_installchangelogs -p$(p_lgcc) + + debian/dh_rmemptydirs -p$(p_lgcc) + PATH=/usr/share/dpkg-cross:$$PATH dh_strip -p$(p_lgcc) + dh_compress -p$(p_lgcc) + dh_fixperms -p$(p_lgcc) +ifeq ($(with_shared_libgcc),yes) + dh_makeshlibs -p$(p_lgcc) -V '$(p_lgcc) (>= $(DEB_LIBGCC_SOVERSION))' -n + sed s/$(cross_lib_arch)//g < debian/$(p_lgcc)/DEBIAN/shlibs > debian/$(p_lgcc)/DEBIAN/shlibs.fixed + mv debian/$(p_lgcc)/DEBIAN/shlibs.fixed debian/$(p_lgcc)/DEBIAN/shlibs + cat debian/$(p_lgcc)/DEBIAN/shlibs >> debian/shlibs.local +endif + ARCH=$(DEB_TARGET_ARCH) MAKEFLAGS="CC=something" dh_shlibdeps -p$(p_lgcc) + sed 's/\(lib[^ ]*\) /\1$(cross_lib_arch) /g' < debian/$(p_lgcc).substvars > debian/$(p_lgcc).substvars.new + mv debian/$(p_lgcc).substvars.new debian/$(p_lgcc).substvars + dh_gencontrol -p$(p_lgcc) \ + -- -v$(DEB_LIBGCC_VERSION) $(common_substvars) + b=libgcc; v=$(GCC_SONAME); \ + for ext in preinst postinst prerm postrm; do \ + if [ -f debian/$$b$$t.$$ext ]; then \ + cp -pf debian/$$b$$t.$$ext debian/$$b$$v$$t.$$ext; \ + fi; \ + done + dh_installdeb -p$(p_lgcc) + dh_md5sums -p$(p_lgcc) + dh_builddeb -p$(p_lgcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64gcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l64gcc) + dh_installdirs -p$(p_l64gcc) \ + $(docdir)/$(p_l64gcc) \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib64 + +ifeq ($(with_shared_libgcc),yes) + mv $(d)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib64/libgcc_s.so.$(GCC_SONAME) $(d_l64gcc)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib64/. +endif + + dh_installdocs -p$(p_l64gcc) + dh_installchangelogs -p$(p_l64gcc) + + debian/dh_rmemptydirs -p$(p_l64gcc) + PATH=/usr/share/dpkg-cross:$$PATH dh_strip -p$(p_l64gcc) + dh_compress -p$(p_l64gcc) + dh_fixperms -p$(p_l64gcc) +ifeq ($(with_shared_libgcc),yes) + dh_makeshlibs -p$(p_l64gcc) \ + -V '$(p_l64gcc) (>= $(DEB_LIBGCC_SOVERSION))' -n + sed s/$(cross_lib_arch)//g < debian/$(p_l64gcc)/DEBIAN/shlibs > debian/$(p_l64gcc)/DEBIAN/shlibs.fixed + mv debian/$(p_l64gcc)/DEBIAN/shlibs.fixed debian/$(p_l64gcc)/DEBIAN/shlibs + cat debian/$(p_l64gcc)/DEBIAN/shlibs >> debian/shlibs.local +endif + ARCH=$(DEB_TARGET_ARCH) MAKEFLAGS="CC=something" dh_shlibdeps -p$(p_l64gcc) + sed 's/\(lib[^ ]*\) /\1$(cross_lib_arch) /g' < debian/$(p_l64gcc).substvars > debian/$(p_l64gcc).substvars.new + mv debian/$(p_l64gcc).substvars.new debian/$(p_l64gcc).substvars + dh_gencontrol -p$(p_l64gcc) \ + -- -v$(DEB_VERSION) $(common_substvars) + b=libgcc; v=$(GCC_SONAME); \ + for ext in preinst postinst prerm postrm; do \ + if [ -f debian/$$b$$t.$$ext ]; then \ + cp -pf debian/$$b$$t.$$ext debian/$$b$$v$$t.$$ext; \ + fi; \ + done + dh_installdeb -p$(p_l64gcc) + dh_md5sums -p$(p_l64gcc) + dh_builddeb -p$(p_l64gcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- + +$(binary_stamp)-lib32gcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l32gcc) + dh_installdirs -p$(p_l32gcc) \ + $(docdir)/$(p_l32gcc) \ + $(PF)/$(DEB_TARGET_GNU_TYPE)/lib32 + +ifeq ($(with_shared_libgcc),yes) + mv $(d)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib32/libgcc_s.so.$(GCC_SONAME) $(d_l32gcc)/$(PF)/$(DEB_TARGET_GNU_TYPE)/lib32/. +endif + + dh_installdocs -p$(p_l32gcc) + dh_installchangelogs -p$(p_l32gcc) + + debian/dh_rmemptydirs -p$(p_l32gcc) + PATH=/usr/share/dpkg-cross:$$PATH dh_strip -p$(p_l32gcc) + dh_compress -p$(p_l32gcc) + dh_fixperms -p$(p_l32gcc) +ifeq ($(with_shared_libgcc),yes) + dh_makeshlibs -p$(p_l32gcc) \ + -V '$(p_l32gcc) (>= $(DEB_LIBGCC_SOVERSION))' -n + sed s/$(cross_lib_arch)//g < debian/$(p_l32gcc)/DEBIAN/shlibs > debian/$(p_l32gcc)/DEBIAN/shlibs.fixed + mv debian/$(p_l32gcc)/DEBIAN/shlibs.fixed debian/$(p_l32gcc)/DEBIAN/shlibs + cat debian/$(p_l32gcc)/DEBIAN/shlibs >> debian/shlibs.local +endif + ARCH=$(DEB_TARGET_ARCH) MAKEFLAGS="CC=something" dh_shlibdeps -p$(p_l32gcc) + sed 's/\(lib[^ ]*\) /\1$(cross_lib_arch) /g' < debian/$(p_l32gcc).substvars > debian/$(p_l32gcc).substvars.new + mv debian/$(p_l32gcc).substvars.new debian/$(p_l32gcc).substvars + dh_gencontrol -p$(p_l32gcc) \ + -- -v$(DEB_VERSION) $(common_substvars) + b=libgcc; v=$(GCC_SONAME); \ + for ext in preinst postinst prerm postrm; do \ + if [ -f debian/$$b$$t.$$ext ]; then \ + cp -pf debian/$$b$$t.$$ext debian/$$b$$v$$t.$$ext; \ + fi; \ + done + dh_installdeb -p$(p_l32gcc) + dh_md5sums -p$(p_l32gcc) + dh_builddeb -p$(p_l32gcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libffi.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libffi.mk @@ -0,0 +1,130 @@ +arch_binaries := $(arch_binaries) libffi +ifeq ($(with_lib64ffi),yes) + arch_binaries := $(arch_binaries) lib64ffi +endif +ifeq ($(with_lib32ffi),yes) + arch_binaries := $(arch_binaries) lib32ffi +endif + +p_ffi = libffi$(FFI_SONAME) +p_l32ffi= lib32ffi$(FFI_SONAME) +p_l64ffi= lib64ffi$(FFI_SONAME) +p_ffid = libffi$(FFI_SONAME)-dev + +d_ffi = debian/$(p_ffi) +d_l32ffi= debian/$(p_l32ffi) +d_l64ffi= debian/$(p_l64ffi) +d_ffid = debian/$(p_ffid) + +dirs_ffi = \ + $(docdir)/$(p_ffi) \ + $(PF)/$(libdir) +files_ffi = \ + $(PF)/$(libdir)/libffi.so.* + +dirs_ffid = \ + $(docdir) \ + $(PF)/include \ + $(gcc_lib_dir)/include +files_ffid = \ + $(gcc_lib_dir)/include/libffi \ + $(PF)/include/{ffi.h,ffitarget.h} \ + $(PF)/$(libdir)/libffi.{a,so,la} + +ifeq ($(with_lib32ffi),yes) + dirs_ffid += $(lib32) + files_ffid += $(lib32)/libffi.{a,so,la} +endif +ifeq ($(with_lib64ffi),yes) + dirs_ffid += $(PF)/lib64 + files_ffid += $(PF)/lib64/libffi.{a,so,la} +endif + +$(binary_stamp)-libffi: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_ffi) $(d_ffid) + dh_installdirs -p$(p_ffi) $(dirs_ffi) + dh_installdirs -p$(p_ffid) $(dirs_ffid) + + mv $(d)/$(gcc_lib_dir)/include/libffi/ffitarget.h $(d)/$(PF)/include/. + + DH_COMPAT=2 dh_movefiles -p$(p_ffi) $(files_ffi) + DH_COMPAT=2 dh_movefiles -p$(p_ffid) $(files_ffid) + + dh_installdocs -p$(p_ffi) $(srcdir)/libffi/README + dh_installchangelogs -p$(p_ffi) $(srcdir)/libffi/ChangeLog + cp -p $(srcdir)/libffi/LICENSE $(d_ffi)/$(docdir)/$(p_ffi)/copyright + cp -p $(srcdir)/libffi/ChangeLog.libgcj \ + $(d_ffi)/$(docdir)/$(p_ffi)/changelog.libgcj + debian/dh_doclink -p$(p_ffid) $(p_ffi) + + debian/dh_rmemptydirs -p$(p_ffi) + debian/dh_rmemptydirs -p$(p_ffid) + + dh_strip -p$(p_ffi) -p$(p_ffid) + dh_compress -p$(p_ffi) -p$(p_ffid) + dh_fixperms -p$(p_ffi) -p$(p_ffid) + dh_makeshlibs -p$(p_ffi) -V '$(p_ffi) (>= $(DEB_FFI_SOVERSION))' + dh_shlibdeps -p$(p_ffi) -p$(p_ffid) + dh_gencontrol -p$(p_ffi) -p$(p_ffid) \ + -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_ffi) -p$(p_ffid) + dh_md5sums -p$(p_ffi) -p$(p_ffid) + dh_builddeb -p$(p_ffi) -p$(p_ffid) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64ffi: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l64ffi) + dh_installdirs -p$(p_l64ffi) \ + $(PF)/lib64 + DH_COMPAT=2 dh_movefiles -p$(p_l64ffi) \ + $(PF)/lib64/libffi.so.* + + debian/dh_doclink -p$(p_l64ffi) $(p_base) + + dh_strip -p$(p_l64ffi) + dh_compress -p$(p_l64ffi) + dh_fixperms -p$(p_l64ffi) + dh_makeshlibs -p$(p_l64ffi) -V '$(p_l64ffi) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l64ffi) + dh_gencontrol -p$(p_l64ffi) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l64ffi) + dh_md5sums -p$(p_l64ffi) + dh_builddeb -p$(p_l64ffi) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32ffi: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l32ffi) + dh_installdirs -p$(p_l32ffi) \ + $(lib32) + DH_COMPAT=2 dh_movefiles -p$(p_l32ffi) \ + $(lib32)/libffi.so.* + + debian/dh_doclink -p$(p_l32ffi) $(p_base) + + dh_strip -p$(p_l32ffi) + dh_compress -p$(p_l32ffi) + dh_fixperms -p$(p_l32ffi) + dh_makeshlibs -p$(p_l32ffi) -V '$(p_l32ffi) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l32ffi) + dh_gencontrol -p$(p_l32ffi) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l32ffi) + dh_md5sums -p$(p_l32ffi) + dh_builddeb -p$(p_l32ffi) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libmudflap.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libmudflap.mk @@ -0,0 +1,125 @@ +arch_binaries := $(arch_binaries) libmudflap +ifeq ($(with_lib64mudflap),yes) + arch_binaries := $(arch_binaries) lib64mudflap +endif +ifeq ($(with_lib32mudflap),yes) + arch_binaries := $(arch_binaries) lib32mudflap +endif + +p_mf = libmudflap$(MUDFLAP_SONAME) +p_l32mf = lib32mudflap$(MUDFLAP_SONAME) +p_l64mf = lib64mudflap$(MUDFLAP_SONAME) +p_mfd = libmudflap$(MUDFLAP_SONAME)-dev + +d_mf = debian/$(p_mf) +d_l32mf = debian/$(p_l32mf) +d_l64mf = debian/$(p_l64mf) +d_mfd = debian/$(p_mfd) + +dirs_mf = \ + $(docdir)/$(p_mf) \ + $(PF)/$(libdir) +files_mf = \ + $(PF)/$(libdir)/libmudflap*.so.* + +dirs_mfd = \ + $(docdir) \ + $(PF)/include \ + $(PF)/$(libdir) +files_mfd = \ + $(PF)/include/mf-runtime.h \ + $(PF)/$(libdir)/libmudflap*.{a,so,la} + +ifeq ($(with_lib32mudflap),yes) + dirs_mfd += $(lib32) + files_mfd += $(lib32)/libmudflap*.{a,so,la} +endif +ifeq ($(with_lib64mudflap),yes) + dirs_mfd += $(PF)/lib64 + files_mfd += $(PF)/lib64/libmudflap*.{a,so,la} +endif + +$(binary_stamp)-libmudflap: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_mf) $(d_mfd) + dh_installdirs -p$(p_mf) $(dirs_mf) + dh_installdirs -p$(p_mfd) $(dirs_mfd) + + DH_COMPAT=2 dh_movefiles -p$(p_mf) $(files_mf) + DH_COMPAT=2 dh_movefiles -p$(p_mfd) $(files_mfd) + + dh_installdocs -p$(p_mf) + dh_installchangelogs -p$(p_mf) $(srcdir)/libmudflap/ChangeLog + cp -p debian/libmudflap.copyright $(d_mf)/$(docdir)/$(p_mf)/copyright + debian/dh_doclink -p$(p_mfd) $(p_mf) + + debian/dh_rmemptydirs -p$(p_mf) + debian/dh_rmemptydirs -p$(p_mfd) + + dh_strip -p$(p_mf) -p$(p_mfd) + dh_compress -p$(p_mf) -p$(p_mfd) + dh_fixperms -p$(p_mf) -p$(p_mfd) + dh_makeshlibs -p$(p_mf) -V '$(p_mf) (>= $(DEB_SOVERSION))' + dh_shlibdeps -p$(p_mf) -p$(p_mfd) + dh_gencontrol -p$(p_mf) -p$(p_mfd) \ + -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_mf) -p$(p_mfd) + dh_md5sums -p$(p_mf) -p$(p_mfd) + dh_builddeb -p$(p_mf) -p$(p_mfd) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64mudflap: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l64mf) + dh_installdirs -p$(p_l64mf) \ + $(PF)/lib64 + DH_COMPAT=2 dh_movefiles -p$(p_l64mf) \ + $(PF)/lib64/libmudflap*.so.* + + debian/dh_doclink -p$(p_l64mf) $(p_base) + + dh_strip -p$(p_l64mf) + dh_compress -p$(p_l64mf) + dh_fixperms -p$(p_l64mf) + dh_makeshlibs -p$(p_l64mf) -V '$(p_l64mf) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l64mf) + dh_gencontrol -p$(p_l64mf) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l64mf) + dh_md5sums -p$(p_l64mf) + dh_builddeb -p$(p_l64mf) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32mudflap: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l32mf) + dh_installdirs -p$(p_l32mf) \ + $(lib32) + DH_COMPAT=2 dh_movefiles -p$(p_l32mf) \ + $(lib32)/libmudflap*.so.* + + debian/dh_doclink -p$(p_l32mf) $(p_base) + + dh_strip -p$(p_l32mf) + dh_compress -p$(p_l32mf) + dh_fixperms -p$(p_l32mf) + dh_makeshlibs -p$(p_l32mf) -V '$(p_l32mf) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_l32mf) + dh_gencontrol -p$(p_l32mf) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_l32mf) + dh_md5sums -p$(p_l32mf) + dh_builddeb -p$(p_l32mf) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-base.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-base.mk @@ -0,0 +1,27 @@ +arch_binaries := base $(arch_binaries) + +# --------------------------------------------------------------------------- +# gcc-base + +$(binary_stamp)-base: $(install_dependencies) + dh_testdir + dh_testroot + rm -rf $(d_base) + dh_installdirs -p$(p_base) + dh_installdocs -p$(p_base) +ifeq ($(with_base_only),yes) + dh_installchangelogs -p$(p_base) +else + dh_installchangelogs -p$(p_base) $(srcdir)/ChangeLog +endif + dh_compress -p$(p_base) + for i in copyright changelog.Debian.gz; do \ + ln -f $(d_base)/usr/share/doc/$(p_base)/$$i \ + $(d_base)/usr/share/doc/$(p_base)/.$$i; \ + done + dh_fixperms -p$(p_base) + dh_gencontrol -p$(p_base) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_base) + dh_md5sums -p$(p_base) + dh_builddeb -p$(p_base) + touch $@ --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libgcc.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libgcc.mk @@ -0,0 +1,157 @@ +ifeq ($(with_libgcc),yes) + arch_binaries := $(arch_binaries) libgcc +endif +ifeq ($(with_lib64gcc),yes) + arch_binaries := $(arch_binaries) lib64gcc +endif +ifeq ($(biarch32),yes) + arch_binaries := $(arch_binaries) lib32gcc +endif + +p_lgcc = libgcc$(GCC_SONAME) +d_lgcc = debian/$(p_lgcc) + +p_l32gcc = lib32gcc$(GCC_SONAME) +d_l32gcc = debian/$(p_l32gcc) + +p_l64gcc = lib64gcc$(GCC_SONAME) +d_l64gcc = debian/$(p_l64gcc) + +# ---------------------------------------------------------------------- +$(binary_stamp)-libgcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lgcc) + dh_installdirs -p$(p_lgcc) \ + $(docdir)/$(p_lgcc) \ + $(libdir) + +ifeq ($(with_shared_libgcc),yes) + mv $(d)/$(PF)/lib/libgcc_s.so.$(GCC_SONAME) $(d_lgcc)/$(libdir)/. +endif + +ifeq ($(with_standalone_gcj)-$(DEB_TARGET_ARCH),yes-hppa) + debian/dh_doclink -p$(p_lgcc) $(p_jbase) +else + debian/dh_doclink -p$(p_lgcc) $(p_base) +endif + debian/dh_rmemptydirs -p$(p_lgcc) + dh_strip -p$(p_lgcc) + dh_compress -p$(p_lgcc) + dh_fixperms -p$(p_lgcc) +ifeq ($(with_shared_libgcc),yes) + dh_makeshlibs -p$(p_lgcc) -V '$(p_lgcc) (>= $(DEB_LIBGCC_SOVERSION))' + cat debian/$(p_lgcc)/DEBIAN/shlibs >> debian/shlibs.local +endif + dh_shlibdeps -p$(p_lgcc) + dh_gencontrol -p$(p_lgcc) \ + -- -v$(DEB_LIBGCC_VERSION) $(common_substvars) + + mkdir -p $(d_lgcc)/usr/share/lintian/overrides + echo '$(p_lgcc): package-name-doesnt-match-sonames' \ + > $(d_lgcc)/usr/share/lintian/overrides/$(p_lgcc) + + dh_installdeb -p$(p_lgcc) + dh_md5sums -p$(p_lgcc) + dh_builddeb -p$(p_lgcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64gcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l64gcc) + dh_installdirs -p$(p_l64gcc) \ + $(docdir)/$(p_l64gcc) \ + lib64 + +ifeq ($(with_shared_libgcc),yes) + mv $(d)/$(PF)/lib64/libgcc_s.so.$(GCC_SONAME) $(d_l64gcc)/lib64/. +endif + + debian/dh_doclink -p$(p_l64gcc) $(p_base) + debian/dh_rmemptydirs -p$(p_l64gcc) + dh_strip -p$(p_l64gcc) + dh_compress -p$(p_l64gcc) + dh_fixperms -p$(p_l64gcc) +ifeq ($(with_shared_libgcc),yes) + dh_makeshlibs -p$(p_l64gcc) \ + -V '$(p_l64gcc) (>= $(DEB_LIBGCC_SOVERSION))' +# this does not work ... shlibs.local doesn't distinguish 32/64 bit libs +# cat debian/$(p_l64gcc)/DEBIAN/shlibs >> debian/shlibs.local +endif +# dh_shlibdeps -p$(p_l64gcc) +#/usr/bin/ldd: line 1: /lib/ld64.so.1: cannot execute binary file +#dpkg-shlibdeps: failure: ldd on `debian/lib64gcc1/lib64/libgcc_s.so.1' gave error exit status 1 +ifeq ($(DEB_TARGET_ARCH),s390) + echo 'shlibs:Depends=libc6-s390x (>= 2.3.1-1)' \ + > debian/$(p_l64gcc).substvars +endif +ifeq ($(DEB_TARGET_ARCH),i386) + echo 'shlibs:Depends=libc6-amd64' \ + > debian/$(p_l64gcc).substvars +endif +ifeq ($(DEB_TARGET_ARCH),sparc) + echo 'shlibs:Depends=libc6-sparc64 (>= 2.3.1-1)' \ + > debian/$(p_l64gcc).substvars +endif +ifeq ($(DEB_TARGET_ARCH),powerpc) + # FIXME change dependency when lib64c6 exists + echo 'shlibs:Depends=libc6 (>= 0.1)' \ + > debian/$(p_l64gcc).substvars +endif + dh_gencontrol -p$(p_l64gcc) \ + -- -v$(DEB_LIBGCC_VERSION) $(common_substvars) + dh_installdeb -p$(p_l64gcc) + dh_md5sums -p$(p_l64gcc) + dh_builddeb -p$(p_l64gcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- + +$(binary_stamp)-lib32gcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_l32gcc) + + dh_installdirs -p$(p_l32gcc) \ + $(docdir)/$(p_l32gcc) \ + $(lib32) + mv $(d)/$(lib32)/libgcc_s.so.$(GCC_SONAME) \ + $(d_l32gcc)/$(lib32)/. + + debian/dh_doclink -p$(p_l32gcc) $(p_base) + debian/dh_rmemptydirs -p$(p_l32gcc) + dh_strip -p$(p_l32gcc) + + dh_makeshlibs -p$(p_l32gcc) \ + -V '$(p_l32gcc) (>= $(DEB_LIBGCC_SOVERSION))' +ifeq ($(DEB_TARGET_ARCH),amd64) + echo 'shlibs:Depends=libc6-i386 | ia32-libs' \ + > debian/$(p_l32gcc).substvars +endif +ifeq ($(DEB_TARGET_ARCH),ppc64) + echo 'shlibs:Depends=libc6-powerpc' \ + > debian/$(p_l32gcc).substvars +endif + + dh_compress -p$(p_l32gcc) + dh_fixperms -p$(p_l32gcc) + dh_gencontrol -p$(p_l32gcc) \ + -- -v$(DEB_LIBGCC_VERSION) $(common_substvars) +ifeq (,$(findstring emul, $(lib32))) + rm -f debian/lib32gcc1.preinst +endif + dh_installdeb -p$(p_l32gcc) + dh_md5sums -p$(p_l32gcc) + dh_builddeb -p$(p_l32gcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-fortran.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-fortran.mk @@ -0,0 +1,236 @@ +ifeq ($(with_libfortran),yes) + arch_binaries := $(arch_binaries) libfortran +endif +ifeq ($(with_lib64fortran),yes) + arch_binaries := $(arch_binaries) lib64fortran +endif +ifeq ($(with_lib32fortran),yes) + arch_binaries := $(arch_binaries) lib32fortran +endif + +ifeq ($(with_fdev),yes) + arch_binaries := $(arch_binaries) fdev libfortran-dev + ifneq ($(GFDL_INVARIANT_FREE),yes) + indep_binaries := $(indep_binaries) fortran-doc + endif +endif + +p_g95 = gfortran$(pkg_ver) +p_g95d = gfortran$(pkg_ver)-doc +p_flib = libgfortran$(FORTRAN_SONAME) +p_f32lib= lib32gfortran$(FORTRAN_SONAME) +p_f64lib= lib64gfortran$(FORTRAN_SONAME) +p_flibd = libgfortran$(FORTRAN_SONAME)-dev + +d_g95 = debian/$(p_g95) +d_g95d = debian/$(p_g95d) +d_flib = debian/$(p_flib) +d_f32lib= debian/$(p_f32lib) +d_f64lib= debian/$(p_f64lib) +d_flibd = debian/$(p_flibd) + +dirs_g95 = \ + $(docdir)/$(p_base)/fortran \ + $(PF)/bin \ + $(gcc_lexec_dir) \ + $(gcc_lib_dir)/include \ + $(PF)/include \ + $(PF)/share/man/man1 +files_g95 = \ + $(PF)/bin/gfortran$(pkg_ver) \ + $(PF)/share/man/man1/gfortran$(pkg_ver).1 \ + $(gcc_lexec_dir)/f951 + + +dirs_flib = \ + $(docdir)/$(p_base)/fortran \ + $(PF)/$(libdir) \ + +files_flib = \ + $(PF)/$(libdir)/libgfortran.so.* + +dirs_flibd = \ + $(docdir)/$(p_base)/fortran \ + $(PF)/$(libdir) \ + +files_flibd = \ + $(PF)/lib/libgfortran.{a,la,so} \ + $(PF)/lib/libgfortranbegin.{a,la} + +ifeq ($(with_lib64fortran),yes) + dirs_flibd += $(PF)/lib64 + files_flibd += \ + $(PF)/lib64/libgfortran.{a,la,so} \ + $(PF)/lib64/libgfortranbegin.{a,la} +endif +ifeq ($(with_lib32fortran),yes) + dirs_flibd += $(lib32) + files_flibd += \ + $(lib32)/libgfortran.{a,la,so} \ + $(lib32)/libgfortranbegin.{a,la} +endif + +# ---------------------------------------------------------------------- +$(binary_stamp)-libfortran: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_flib) + dh_installdirs -p$(p_flib) $(dirs_flib) + DH_COMPAT=2 dh_movefiles -p$(p_flib) $(files_flib) + debian/dh_doclink -p$(p_flib) $(p_base) + + dh_strip -p$(p_flib) + dh_compress -p$(p_flib) + dh_fixperms -p$(p_flib) + dh_makeshlibs -p$(p_flib) -V '$(p_flib) (>= $(DEB_SOVERSION))' + dh_shlibdeps -p$(p_flib) + dh_gencontrol -p$(p_flib) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_flib) + dh_md5sums -p$(p_flib) + dh_builddeb -p$(p_flib) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-libfortran-dev: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_flibd) + dh_installdirs -p$(p_flibd) $(dirs_flibd) + DH_COMPAT=2 dh_movefiles -p$(p_flibd) $(files_flibd) + debian/dh_doclink -p$(p_flibd) $(p_base) + + debian/dh_rmemptydirs -p$(p_flibd) + + dh_strip -p$(p_flibd) + dh_compress -p$(p_flibd) + dh_fixperms -p$(p_flibd) + dh_shlibdeps -p$(p_flibd) + dh_gencontrol -p$(p_flibd) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_flibd) + dh_md5sums -p$(p_flibd) + dh_builddeb -p$(p_flibd) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64fortran: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_f64lib) + dh_installdirs -p$(p_f64lib) \ + $(PF)/lib64 + DH_COMPAT=2 dh_movefiles -p$(p_f64lib) \ + $(PF)/lib64/libgfortran.so.* + + debian/dh_doclink -p$(p_f64lib) $(p_base) + + dh_strip -p$(p_f64lib) + dh_compress -p$(p_f64lib) + dh_fixperms -p$(p_f64lib) + dh_makeshlibs -p$(p_f64lib) -V '$(p_f64lib) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_f64lib) + dh_gencontrol -p$(p_f64lib) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_f64lib) + dh_md5sums -p$(p_f64lib) + dh_builddeb -p$(p_f64lib) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32fortran: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_f32lib) + dh_installdirs -p$(p_f32lib) \ + $(lib32) + DH_COMPAT=2 dh_movefiles -p$(p_f32lib) \ + $(lib32)/libgfortran.so.* + + debian/dh_doclink -p$(p_f32lib) $(p_base) + + dh_strip -p$(p_f32lib) + dh_compress -p$(p_f32lib) + dh_fixperms -p$(p_f32lib) + dh_makeshlibs -p$(p_f32lib) -V '$(p_f32lib) (>= $(DEB_SOVERSION))' +# dh_shlibdeps -p$(p_f32lib) + dh_gencontrol -p$(p_f32lib) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_f32lib) + dh_md5sums -p$(p_f32lib) + dh_builddeb -p$(p_f32lib) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-fdev: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_g95) + dh_installdirs -p$(p_g95) $(dirs_g95) + + DH_COMPAT=2 dh_movefiles -p$(p_g95) $(files_g95) + + ln -sf gfortran$(pkg_ver) \ + $(d_g95)/$(PF)/bin/$(DEB_TARGET_GNU_TYPE)-gfortran$(pkg_ver) + ln -sf gfortran$(pkg_ver).1 \ + $(d_g95)/$(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-gfortran$(pkg_ver).1 + ln -sf gfortran$(pkg_ver) \ + $(d_g95)/$(PF)/bin/$(TARGET_ALIAS)-gfortran$(pkg_ver) + ln -sf gfortran$(pkg_ver).1 \ + $(d_g95)/$(PF)/share/man/man1/$(TARGET_ALIAS)-gfortran$(pkg_ver).1 + + debian/dh_doclink -p$(p_g95) $(p_base) + + cp -p $(srcdir)/gcc/fortran/ChangeLog \ + $(d_g95)/$(docdir)/$(p_base)/fortran/changelog + debian/dh_rmemptydirs -p$(p_g95) + + dh_strip -p$(p_g95) + dh_compress -p$(p_g95) + dh_fixperms -p$(p_g95) + dh_shlibdeps -p$(p_g95) + dh_gencontrol -p$(p_g95) -- -v$(DEB_VERSION) $(common_substvars) + dh_installdeb -p$(p_g95) + dh_md5sums -p$(p_g95) + dh_builddeb -p$(p_g95) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-fortran-doc: $(build_html_stamp) $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_g95d) + dh_installdirs -p$(p_g95d) \ + $(docdir)/$(p_base)/fortran \ + $(PF)/share/info + DH_COMPAT=2 dh_movefiles -p$(p_g95d) \ + $(PF)/share/info/gfortran* + + debian/dh_doclink -p$(p_g95d) $(p_base) +ifneq ($(GFDL_INVARIANT_FREE),yes) + dh_installdocs -p$(p_g95d) + rm -f $(d_g95d)/$(docdir)/$(p_base)/copyright + cp -p html/gfortran.html $(d_g95d)/$(docdir)/$(p_base)/fortran/ +endif + + dh_compress -p$(p_g95d) + dh_fixperms -p$(p_g95d) + dh_installdeb -p$(p_g95d) + dh_gencontrol -p$(p_g95d) -- -v$(DEB_VERSION) $(common_substvars) + dh_md5sums -p$(p_g95d) + dh_builddeb -p$(p_g95d) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-gcc-cross.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-gcc-cross.mk @@ -0,0 +1,109 @@ +arch_binaries := $(arch_binaries) gcc + +# gcc must be moved after g77 and g++ +# not all files $(PF)/include/*.h are part of gcc, +# but it becomes difficult to name all these files ... + +dirs_gcc = \ + $(PF)/bin \ + $(gcc_lexec_dir) \ + $(gcc_lib_dir)/include \ + $(PF)/share/man/man1 $(libdir) + +files_gcc = \ + $(PF)/bin/$(DEB_TARGET_GNU_TYPE)-gcc$(pkg_ver) \ + $(PF)/share/man/man1/$(DEB_TARGET_GNU_TYPE)-gcc$(pkg_ver).1 \ + $(gcc_lexec_dir)/collect2 \ + $(gcc_lib_dir)/{libgcc*,*.o} \ + $(gcc_lib_dir)/include/README \ + $(gcc_lib_dir)/include/{float,iso646,limits,std*,syslimits,unwind,varargs}.h \ + $(shell for d in asm bits gnu linux; do \ + test -e $(d)/$(gcc_lib_dir)/include/$$d \ + && echo $(gcc_lib_dir)/include/$$d; \ + done) \ + $(shell test -e $(d)/$(gcc_lib_dir)/SYSCALLS.c.X \ + && echo $(gcc_lib_dir)/SYSCALLS.c.X) \ + $(shell for h in {,e,p,x}mmintrin.h mm3dnow.h mm_malloc.h; do \ + test -e $(d)/$(gcc_lib_dir)/include/$$h \ + && echo $(gcc_lib_dir)/include/$$h; \ + done) \ + + +ifeq ($(biarch),yes) + files_gcc += $(gcc_lib_dir)/$(biarchsubdir)/{libgcc*,*.o} +endif +ifeq ($(biarch32),yes) + files_gcc += $(gcc_lib_dir)/$(biarchsubdir)/{libgcc*,*.o} +endif + +ifeq ($(DEB_TARGET_ARCH),ia64) + files_gcc += $(gcc_lib_dir)/include/ia64intrin.h +endif + +ifeq ($(DEB_TARGET_ARCH),m68k) + files_gcc += $(gcc_lib_dir)/include/math-68881.h +endif + +ifeq ($(DEB_TARGET_ARCH),$(findstring $(DEB_TARGET_ARCH),powerpc ppc64)) + files_gcc += $(gcc_lib_dir)/include/{altivec.h,ppc-asm.h} +endif + +usr_doc_files = debian/README.Bugs \ + $(shell test -f $(srcdir)/FAQ && echo $(srcdir)/FAQ) +ifeq ($(with_check),yes) + usr_doc_files += test-summary +endif + +# ---------------------------------------------------------------------- +$(binary_stamp)-gcc: $(install_dependencies) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_gcc) + dh_installdirs -p$(p_gcc) $(dirs_gcc) + + rm -f $(d)/$(PF)/$(libdir)/libgcc_s.so + ln -sf /$(PF)/$(DEB_TARGET_GNU_TYPE)/$(libdir)/libgcc_s.so.$(GCC_SONAME) $(d)/$(gcc_lib_dir)/libgcc_s.so +ifeq ($(biarch),yes) + rm -f $(d)/$(PF)/$(lib64)/libgcc_s.so + dh_link -p$(p_gcc) \ + /$(PF)/$(DEB_TARGET_GNU_TYPE)/$(lib64)/libgcc_s.so.$(GCC_SONAME) /$(gcc_lib_dir)/libgcc_s_64.so \ + /$(PF)/$(DEB_TARGET_GNU_TYPE)/$(lib64)/libgcc_s.so.$(GCC_SONAME) /$(gcc_lib_dir)/$(biarchsubdir)/libgcc_s.so +endif +ifeq ($(biarch32),yes) + mkdir -p $(d_gcc)/$(gcc_lib_dir) + mv $(d)/$(gcc_lib_dir)/$(biarchsubdir) $(d_gcc)/$(gcc_lib_dir)/ + dh_link -p$(p_gcc) \ + /$(PF)/$(DEB_TARGET_GNU_TYPE)/lib32/libgcc_s.so.$(GCC_SONAME) /$(gcc_lib_dir)/libgcc_s_32.so \ + /$(PF)/$(DEB_TARGET_GNU_TYPE)/lib32/libgcc_s.so.$(GCC_SONAME) /$(gcc_lib_dir)/$(biarchsubdir)/libgcc_s_32.so \ + /$(PF)/$(DEB_TARGET_GNU_TYPE)/lib32/libgcc_s.so.$(GCC_SONAME) /$(gcc_lib_dir)/$(biarchsubdir)/libgcc_s.so +endif + + DH_COMPAT=2 dh_movefiles -p$(p_gcc) $(files_gcc) + +# dh_installdebconf + debian/dh_doclink -p$(p_gcc) $(p_base) + debian/dh_rmemptydirs -p$(p_gcc) + PATH=/usr/share/dpkg-cross:$$PATH dh_strip -p$(p_gcc) + dh_compress -p$(p_gcc) + dh_fixperms -p$(p_gcc) + dh_shlibdeps -p$(p_gcc) + dh_gencontrol -p$(p_gcc) -- -v$(DEB_VERSION) $(common_substvars) + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g' < debian/gcc-cross.postinst > debian/$(p_gcc)/DEBIAN/postinst + sed 's/cross-/$(TP)/g;s/-ver/$(pkg_ver)/g' < debian/gcc-cross.prerm > debian/$(p_gcc)/DEBIAN/prerm + chmod 755 debian/$(p_gcc)/DEBIAN/{postinst,prerm} + dh_installdeb -p$(p_gcc) + dh_md5sums -p$(p_gcc) + dh_builddeb -p$(p_gcc) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + + : # remove empty directories, when all components are in place + for d in `find $(d) -depth -type d -empty 2> /dev/null`; do \ + while rmdir $$d 2> /dev/null; do d=`dirname $$d`; done; \ + done + + @echo "Listing installed files not included in any package:" + -find $(d) ! -type d + --- gcj-4.1-4.1.1.orig/debian/rules.d/binary-libstdcxx.mk +++ gcj-4.1-4.1.1/debian/rules.d/binary-libstdcxx.mk @@ -0,0 +1,450 @@ + +ifeq ($(with_libcxx),yes) + arch_binaries := $(arch_binaries) libstdcxx +endif +ifeq ($(with_lib64cxx),yes) + arch_binaries := $(arch_binaries) lib64stdcxx +endif +ifeq ($(with_lib64cxxdbg),yes) + arch_binaries := $(arch_binaries) lib64stdcxxdbg +endif +ifeq ($(with_lib32cxx),yes) + arch_binaries := $(arch_binaries) lib32stdcxx +endif +ifeq ($(with_lib32cxxdbg),yes) + arch_binaries := $(arch_binaries) lib32stdcxxdbg +endif + +ifeq ($(with_cxxdev),yes) + arch_binaries := $(arch_binaries) libstdcxx-dev + indep_binaries := $(indep_binaries) libstdcxx-doc +endif + +libstdc_ext = -$(BASE_VERSION) + +p_lib = libstdc++$(CXX_SONAME) +p_lib64 = lib64stdc++$(CXX_SONAME) +p_lib32 = lib32stdc++$(CXX_SONAME) +p_dev = libstdc++$(CXX_SONAME)$(libstdc_ext)-dev +p_pic = libstdc++$(CXX_SONAME)$(libstdc_ext)-pic +p_dbg = libstdc++$(CXX_SONAME)$(libstdc_ext)-dbg +p_dbg64 = $(p_lib64)$(libstdc_ext)-dbg +p_dbg32 = $(p_lib32)$(libstdc_ext)-dbg +p_libd = libstdc++$(CXX_SONAME)$(libstdc_ext)-doc + +d_lib = debian/$(p_lib) +d_lib64 = debian/$(p_lib64) +d_lib32 = debian/$(p_lib32) +d_dev = debian/$(p_dev) +d_pic = debian/$(p_pic) +d_dbg = debian/$(p_dbg) +d_dbg64 = debian/$(p_dbg64) +d_dbg32 = debian/$(p_dbg32) +d_libd = debian/$(p_libd) + +dirs_dev = \ + $(docdir)/$(p_base)/C++ \ + $(PF)/$(libdir) \ + $(gcc_lib_dir)/include \ + $(cxx_inc_dir) + +files_dev = \ + $(cxx_inc_dir)/ \ + $(gcc_lib_dir)/libstdc++.{a,so} \ + $(gcc_lib_dir)/libsupc++.a +# Not yet... +# $(PF)/$(libdir)/lib{supc,stdc}++.la + +dirs_dbg = \ + $(docdir) \ + $(PF)/$(libdir)/debug \ + $(gcc_lib_dir) +files_dbg = \ + $(PF)/$(libdir)/debug/libstdc++.* + +dirs_pic = \ + $(docdir) \ + $(gcc_lib_dir) +files_pic = \ + $(gcc_lib_dir)/libstdc++_pic.a + +ifeq ($(biarch),yes) + dirs_dev += $(gcc_lib_dir)/$(biarchsubdir)/ + files_dev += $(gcc_lib_dir)/$(biarchsubdir)/libstdc++.{a,so} \ + $(gcc_lib_dir)/$(biarchsubdir)/libsupc++.a + dirs_pic += $(gcc_lib_dir) + files_pic += $(gcc_lib_dir)/$(biarchsubdir)/libstdc++_pic.a +endif +ifeq ($(biarch32),yes) + dirs_dev += $(gcc_lib_dir)/$(biarchsubdir)/ + files_dev += $(gcc_lib_dir)/$(biarchsubdir)/libstdc++.{a,so} \ + $(gcc_lib_dir)/$(biarchsubdir)/libsupc++.a + dirs_pic += $(gcc_lib_dir) + files_pic += $(gcc_lib_dir)/$(biarchsubdir)/libstdc++_pic.a +endif + +# ---------------------------------------------------------------------- + +gxx_baseline_dir = $(shell \ + sed -n '/^baseline_dir *=/s,.*= *\(.*\)\$$.*$$,\1,p' \ + $(buildlibdir)/libstdc++-v3/testsuite/Makefile) +gxx_baseline_file = $(gxx_baseline_dir)/baseline_symbols.txt + +debian/README.libstdc++-baseline: + cat debian/README.libstdc++-baseline.in \ + > debian/README.libstdc++-baseline + + baseline_name=`basename $(gxx_baseline_dir)`; \ + baseline_parentdir=`dirname $(gxx_baseline_dir)`; \ + compat_baseline_name=""; \ + if [ -f "$(gxx_baseline_file)" ]; then \ + ( \ + echo "A baseline file for $$baseline_name was found."; \ + echo "Running the check-abi script ..."; \ + echo ""; \ + $(MAKE) -C $(buildlibdir)/libstdc++-v3/testsuite \ + check-abi; \ + ) >> debian/README.libstdc++-baseline; \ + else \ + ( \ + echo "No baseline file found for $$baseline_name."; \ + echo "Generating a new baseline file ..."; \ + echo ""; \ + ) >> debian/README.libstdc++-baseline; \ + mkdir $(gxx_baseline_dir); \ + $(MAKE) -C $(buildlibdir)/libstdc++-v3/testsuite new-abi-baseline; \ + cat $(gxx_baseline_file) >> debian/README.libstdc++-baseline; \ + fi + +# ---------------------------------------------------------------------- +$(binary_stamp)-libstdcxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lib) + dh_installdirs -p$(p_lib) \ + $(docdir) \ + $(PF)/$(libdir) + + cp -a $(d)/$(PF)/$(libdir)/libstdc++.so.* \ + $(d_lib)/$(PF)/$(libdir)/ + + debian/dh_doclink -p$(p_lib) $(p_base) + debian/dh_rmemptydirs -p$(p_lib) + + dh_strip -p$(p_lib) + dh_compress -p$(p_lib) + dh_fixperms -p$(p_lib) + dh_makeshlibs -p$(p_lib) -V '$(p_lib) (>= $(DEB_STDCXX_SOVERSION))' + cat debian/$(p_lib)/DEBIAN/shlibs >> debian/shlibs.local + dh_shlibdeps \ + -L$(p_lgcc) -l:$(d)/$(PF)/lib:$(d_lgcc)/lib:\ + -p$(p_lib) + dh_gencontrol -p$(p_lib) -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_lib) + dh_md5sums -p$(p_lib) + dh_builddeb -p$(p_lib) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64stdcxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lib64) + dh_installdirs -p$(p_lib64) \ + $(docdir) \ + $(PF)/lib64 + + cp -a $(d)/$(PF)/lib64/libstdc++.so.* \ + $(d_lib64)/$(PF)/lib64/. + + dh_strip -p$(p_lib64) + + debian/dh_doclink -p$(p_lib64) $(p_base) + debian/dh_rmemptydirs -p$(p_lib64) + + dh_compress -p$(p_lib64) + dh_fixperms -p$(p_lib64) + dh_makeshlibs -p$(p_lib64) -V '$(p_lib64) (>= $(DEB_STDCXX_SOVERSION))' +# pass explicit dependencies to dh_shlibdeps +# dh_shlibdeps -p$(p_lib64) -L $(p_l64gcc) -l $(d_l64gcc)/lib +#/usr/bin/ldd: line 1: /lib/ld64.so.1: cannot execute binary file +#dpkg-shlibdeps: failure: ldd on `debian/lib64gcc1/lib64/libgcc_s.so.1' gave error exit status 1 + echo 'shlibs:Depends=$(p_l64gcc) (>= $(DEB_LIBGCC_SOVERSION))' \ + > debian/$(p_lib64).substvars + dh_gencontrol -p$(p_lib64) -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_lib64) + dh_md5sums -p$(p_lib64) + dh_builddeb -p$(p_lib64) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib64stdcxxdbg: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_dbg64) + dh_installdirs -p$(p_dbg64) \ + $(PF)/lib64 + + cp -a $(d)/$(PF)/lib64/libstdc++.so.* \ + $(d_dbg64)/$(PF)/lib64/. + dh_strip -p$(p_dbg64) --keep-debug + rm -f $(d_dbg64)/$(PF)/lib64/libstdc++.so.* + +# mv $(d)/$(PF)/lib64/debug $(d_dbg64)/$(PF)/lib64/. + rm -f $(d_dbg64)/$(PF)/lib64/debug/libstdc++_pic.a + + debian/dh_doclink -p$(p_dbg64) $(p_base) + debian/dh_rmemptydirs -p$(p_dbg64) + + dh_compress -p$(p_dbg64) + dh_fixperms -p$(p_dbg64) + dh_gencontrol -p$(p_dbg64) -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_dbg64) + dh_md5sums -p$(p_dbg64) + dh_builddeb -p$(p_dbg64) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32stdcxx: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_lib32) + + dh_installdirs -p$(p_lib32) \ + $(docdir) \ + $(lib32) + + cp -a $(d)/$(lib32)/libstdc++.so.* \ + $(d_lib32)/$(lib32)/. + + debian/dh_doclink -p$(p_lib32) $(p_base) + debian/dh_rmemptydirs -p$(p_lib32) + + dh_strip -p$(p_lib32) + dh_compress -p$(p_lib32) + dh_fixperms -p$(p_lib32) + dh_makeshlibs -p$(p_lib32) -V '$(p_lib32) (>= $(DEB_STDCXX_SOVERSION))' + dh_gencontrol -p$(p_lib32) -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_lib32) + dh_md5sums -p$(p_lib32) + dh_builddeb -p$(p_lib32) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +$(binary_stamp)-lib32stdcxxdbg: $(install_stamp) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_dbg32) + dh_installdirs -p$(p_dbg32) \ + $(lib32) + + cp -a $(d)/$(lib32)/libstdc++.so.* \ + $(d_dbg32)/$(lib32)/. + dh_strip -p$(p_dbg32) --keep-debug + rm -f $(d_dbg32)/$(lib32)/libstdc++.so.* + + mv $(d)/$(lib32)/debug $(d_dbg32)/$(lib32)/. + rm -f $(d_dbg32)/$(lib32)/debug/libstdc++_pic.a + + debian/dh_doclink -p$(p_dbg32) $(p_base) + debian/dh_rmemptydirs -p$(p_dbg32) + + dh_compress -p$(p_dbg32) + dh_fixperms -p$(p_dbg32) + dh_gencontrol -p$(p_dbg32) -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_dbg32) + dh_md5sums -p$(p_dbg32) + dh_builddeb -p$(p_dbg32) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- +libcxxdev_deps = $(install_stamp) +ifeq ($(with_libcxx),yes) + libcxxdev_deps += $(binary_stamp)-libstdcxx +endif +ifeq ($(with_check),yes) + libcxxdev_deps += debian/README.libstdc++-baseline +endif +$(binary_stamp)-libstdcxx-dev: $(libcxxdev_deps) + dh_testdir + dh_testroot + mv $(install_stamp) $(install_stamp)-tmp + + rm -rf $(d_dev) $(d_pic) + dh_installdirs -p$(p_dev) $(dirs_dev) + dh_installdirs -p$(p_pic) $(dirs_pic) + dh_installdirs -p$(p_dbg) $(dirs_dbg) + + : # - correct libstdc++-v3 file locations + mv $(d)/$(PF)/$(libdir)/libsupc++.a $(d)/$(gcc_lib_dir)/ + mv $(d)/$(PF)/$(libdir)/libstdc++.{a,so} $(d)/$(gcc_lib_dir)/ + ln -sf ../../../$(DEB_TARGET_GNU_TYPE)/libstdc++.so.$(CXX_SONAME) \ + $(d)/$(gcc_lib_dir)/libstdc++.so + mv $(d)/$(PF)/$(libdir)/libstdc++_pic.a $(d)/$(gcc_lib_dir)/ + + rm -f $(d)/$(PF)/$(libdir)/debug/libstdc++_pic.a + rm -f $(d)/$(PF)/lib64/debug/libstdc++_pic.a + + : # remove precompiled headers + -find $(d) -type d -name '*.gch' | xargs rm -rf + +ifeq ($(biarch),yes) + mv $(d)/$(PF)/lib64/lib*c++*.{a,so} $(d)/$(gcc_lib_dir)/$(biarchsubdir)/. +endif +ifeq ($(biarch32),yes) + mv $(d)/$(lib32)/lib*c++*.{a,so} $(d)/$(gcc_lib_dir)/$(biarchsubdir)/. +endif + + for i in $(d)/$(PF)/include/c++/$(GCC_VERSION)/*-linux; do \ + if [ -d $$i ]; then mv $$i $$i-gnu; fi; \ + done + + DH_COMPAT=2 dh_movefiles -p$(p_dev) $(files_dev) + DH_COMPAT=2 dh_movefiles -p$(p_pic) $(files_pic) + DH_COMPAT=2 dh_movefiles -p$(p_dbg) $(files_dbg) + + dh_link -p$(p_dev) \ + /$(PF)/$(libdir)/libstdc++.so.$(CXX_SONAME) \ + /$(gcc_lib_dir)/libstdc++.so \ + /$(cxx_inc_dir) /$(PF)/include/c++/$(BASE_VERSION) + +ifeq ($(biarch),yes) + dh_link -p$(p_dev) \ + /$(PF)/lib64/libstdc++.so.$(CXX_SONAME) \ + /$(gcc_lib_dir)/$(biarchsubdir)/libstdc++.so +endif +ifeq ($(biarch32),yes) + dh_link -p$(p_dev) \ + /$(lib32)/libstdc++.so.$(CXX_SONAME) \ + /$(gcc_lib_dir)/$(biarchsubdir)/libstdc++.so +endif + + debian/dh_doclink -p$(p_dev) $(p_base) + debian/dh_doclink -p$(p_pic) $(p_base) + debian/dh_doclink -p$(p_dbg) $(p_base) + cp -p $(srcdir)/libstdc++-v3/ChangeLog \ + $(d_dev)/$(docdir)/$(p_base)/C++/changelog.libstdc++ +ifeq ($(with_check),yes) + cp -p debian/README.libstdc++-baseline \ + $(d_dev)/$(docdir)/$(p_base)/C++/README.libstdc++-baseline + if [ -f $(buildlibdir)/libstdc++-v3/testsuite/current_symbols.txt ]; \ + then \ + cp -p $(buildlibdir)/libstdc++-v3/testsuite/current_symbols.txt \ + $(d_dev)/$(docdir)/$(p_base)/C++/libstdc++_symbols.txt; \ + fi +endif + cp -p $(srcdir)/libstdc++-v3/config/linker-map.gnu \ + $(d_pic)/$(gcc_lib_dir)/libstdc++_pic.map + +ifeq ($(with_cxxdev),yes) + debian/dh_rmemptydirs -p$(p_dev) + debian/dh_rmemptydirs -p$(p_pic) + debian/dh_rmemptydirs -p$(p_dbg) +endif + + cp -a $(d)/$(PF)/$(libdir)/libstdc++.so.* \ + $(d_dbg)/$(PF)/$(libdir)/ + dh_strip -p$(p_dbg) --keep-debug + rm -f $(d_dbg)/$(PF)/$(libdir)/libstdc++.so.* + + dh_strip -p$(p_dev) --dbg-package=$(p_lib) + dh_strip -p$(p_pic) + + dh_compress -p$(p_dev) -p$(p_pic) -p$(p_dbg) -X.txt + dh_fixperms -p$(p_dev) -p$(p_pic) -p$(p_dbg) +ifeq ($(biarch),yes) + dh_shlibdeps -p$(p_dev) -p$(p_pic) -p$(p_dbg) -Xlib64 +else + dh_shlibdeps -p$(p_dev) -p$(p_pic) -p$(p_dbg) -Xlib32/debug +endif + dh_gencontrol -p$(p_dev) -p$(p_pic) -p$(p_dbg) \ + -- -v$(DEB_VERSION) $(common_substvars) + + dh_installdeb -p$(p_dev) -p$(p_pic) -p$(p_dbg) + dh_md5sums -p$(p_dev) -p$(p_pic) -p$(p_dbg) + dh_builddeb -p$(p_dev) -p$(p_pic) -p$(p_dbg) + + trap '' 1 2 3 15; touch $@; mv $(install_stamp)-tmp $(install_stamp) + +# ---------------------------------------------------------------------- + +doxygen_doc_dir = $(buildlibdir)/libstdc++-v3/docs/doxygen + +doxygen-docs: $(build_doxygen_stamp) +$(build_doxygen_stamp): + rm -rf $(doxygen_doc_dir)/html* + $(MAKE) -C $(buildlibdir)/libstdc++-v3 SHELL=/bin/bash doxygen + $(MAKE) -C $(buildlibdir)/libstdc++-v3 SHELL=/bin/bash doxygen-man + sed -e 's,http://gcc\.gnu\.org/onlinedocs/libstdc++,../html,g' \ + -e 's,
tabPlacement
, where tabPlacement
can be one
++ * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
++ * {@link #RIGHT}.
+ *
+- * @param tabPlacement Where the tabs will be placed.
++ * @param tabPlacement where the tabs will be placed
+ */
+ public JTabbedPane(int tabPlacement)
+ {
+@@ -602,11 +604,14 @@
+ }
+
+ /**
+- * Creates a new JTabbedPane object with the given tabPlacement and
+- * tabLayoutPolicy.
++ * Creates a new JTabbedPane object with the given tabPlacement
++ * and tabLayoutPolicy
. The tabPlacement
can be one
++ * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
++ * {@link #RIGHT}. The tabLayoutPolicy
can be either
++ * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}.
+ *
+- * @param tabPlacement Where the tabs will be placed.
+- * @param tabLayoutPolicy The way tabs will be placed.
++ * @param tabPlacement where the tabs will be placed
++ * @param tabLayoutPolicy the way tabs will be placed
+ *
+ * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
+ * not valid.
+@@ -913,7 +918,7 @@
+ if (getSelectedIndex() == -1)
+ setSelectedIndex(0);
+
+- layout();
++ revalidate();
+ repaint();
+ }
+
+Index: libjava/classpath/javax/swing/JInternalFrame.java
+===================================================================
+--- libjava/classpath/javax/swing/JInternalFrame.java (revision 111438)
++++ libjava/classpath/javax/swing/JInternalFrame.java (working copy)
+@@ -1628,7 +1628,6 @@
+ {
+ if (! isVisible())
+ {
+- moveToFront();
+ super.show();
+
+ JDesktopPane pane = getDesktopPane();
+Index: libjava/classpath/javax/swing/JViewport.java
+===================================================================
+--- libjava/classpath/javax/swing/JViewport.java (revision 111438)
++++ libjava/classpath/javax/swing/JViewport.java (working copy)
+@@ -38,6 +38,8 @@
+
+ package javax.swing;
+
++import gnu.classpath.SystemProperties;
++
+ import java.awt.Component;
+ import java.awt.Dimension;
+ import java.awt.Graphics;
+@@ -163,7 +165,13 @@
+ public static final int BACKINGSTORE_SCROLL_MODE = 2;
+
+ private static final long serialVersionUID = -6925142919680527970L;
+-
++
++ /**
++ * The default scrollmode to be used by all JViewports as determined by
++ * the system property gnu.javax.swing.JViewport.scrollMode.
++ */
++ private static final int defaultScrollMode;
++
+ protected boolean scrollUnderway;
+ protected boolean isViewSizeSet;
+
+@@ -243,21 +251,26 @@
+ */
+ boolean sizeChanged = true;
+
+- public JViewport()
++ /**
++ * Initializes the default setting for the scrollMode property.
++ */
++ static
+ {
+- setOpaque(true);
+ String scrollModeProp =
+- System.getProperty("gnu.javax.swing.JViewport.scrollMode",
++ SystemProperties.getProperty("gnu.javax.swing.JViewport.scrollMode",
+ "BLIT");
+- int myScrollMode;
+ if (scrollModeProp.equalsIgnoreCase("simple"))
+- myScrollMode = SIMPLE_SCROLL_MODE;
++ defaultScrollMode = SIMPLE_SCROLL_MODE;
+ else if (scrollModeProp.equalsIgnoreCase("backingstore"))
+- myScrollMode = BACKINGSTORE_SCROLL_MODE;
++ defaultScrollMode = BACKINGSTORE_SCROLL_MODE;
+ else
+- myScrollMode = BLIT_SCROLL_MODE;
+- setScrollMode(myScrollMode);
++ defaultScrollMode = BLIT_SCROLL_MODE;
++ }
+
++ public JViewport()
++ {
++ setOpaque(true);
++ setScrollMode(defaultScrollMode);
+ updateUI();
+ setLayout(createLayoutManager());
+ lastPaintPosition = new Point();
+@@ -410,8 +423,9 @@
+
+ public void setView(Component v)
+ {
+- if (viewListener != null)
+- getView().removeComponentListener(viewListener);
++ Component currView = getView();
++ if (viewListener != null && currView != null)
++ currView.removeComponentListener(viewListener);
+
+ if (v != null)
+ {
+@@ -772,6 +786,9 @@
+ */
+ void paintSimple(Graphics g)
+ {
++ // We need to call this to properly clear the background.
++ paintComponent(g);
++
+ Point pos = getViewPosition();
+ Component view = getView();
+ boolean translated = false;
+Index: libjava/classpath/javax/swing/JMenuItem.java
+===================================================================
+--- libjava/classpath/javax/swing/JMenuItem.java (revision 111438)
++++ libjava/classpath/javax/swing/JMenuItem.java (working copy)
+@@ -1,5 +1,5 @@
+ /* JMenuItem.java --
+- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
++ Copyright (C) 2002, 2004, 2005,2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+@@ -117,6 +117,24 @@
+ super();
+ super.setAction(action);
+ init(null, null);
++ if (action != null)
++ {
++ String name = (String) action.getValue(Action.NAME);
++ if (name != null)
++ setName(name);
++
++ KeyStroke accel = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY);
++ if (accel != null)
++ setAccelerator(accel);
++
++ Integer mnemonic = (Integer) action.getValue(Action.MNEMONIC_KEY);
++ if (mnemonic != null)
++ setMnemonic(mnemonic.intValue());
++
++ String command = (String) action.getValue(Action.ACTION_COMMAND_KEY);
++ if (command != null)
++ setActionCommand(command);
++ }
+ }
+
+ /**
+@@ -273,8 +291,9 @@
+ if (! (this instanceof JMenu) && action != null)
+ {
+ setAccelerator((KeyStroke) (action.getValue(Action.ACCELERATOR_KEY)));
+- super.registerKeyboardAction(action, accelerator,
+- JComponent.WHEN_IN_FOCUSED_WINDOW);
++ if (accelerator != null)
++ super.registerKeyboardAction(action, accelerator,
++ JComponent.WHEN_IN_FOCUSED_WINDOW);
+ }
+ }
+
+Index: libjava/classpath/javax/swing/JTextPane.java
+===================================================================
+--- libjava/classpath/javax/swing/JTextPane.java (revision 111438)
++++ libjava/classpath/javax/swing/JTextPane.java (working copy)
+@@ -40,6 +40,7 @@
+
+ import java.awt.Component;
+
++import javax.swing.text.AbstractDocument;
+ import javax.swing.text.AttributeSet;
+ import javax.swing.text.BadLocationException;
+ import javax.swing.text.Caret;
+@@ -151,38 +152,34 @@
+ {
+ Caret caret = getCaret();
+ StyledDocument doc = getStyledDocument();
++ AttributeSet a = getInputAttributes().copyAttributes();
++ if (doc == null)
++ return;
+
+ int dot = caret.getDot();
+ int mark = caret.getMark();
+
+- // If content is empty delete selection.
+- if (content == null)
+- {
+- caret.setDot(dot);
+- return;
+- }
++ int p0 = Math.min (dot, mark);
++ int p1 = Math.max (dot, mark);
+
+ try
+ {
+- int start = getSelectionStart();
+- int end = getSelectionEnd();
+- int contentLength = content.length();
+-
+- // Remove selected text.
+- if (dot != mark)
+- doc.remove(start, end - start);
+-
+- // Insert new text.
+- doc.insertString(start, content, null);
+- // Set attributes for inserted text
+- doc.setCharacterAttributes(start, contentLength, getInputAttributes(),
+- true);
+-
++ if (doc instanceof AbstractDocument)
++ ((AbstractDocument)doc).replace(p0, p1 - p0, content, a);
++ else
++ {
++ // Remove selected text.
++ if (dot != mark)
++ doc.remove(p0, p1 - p0);
++ // Insert new text.
++ if (content != null && content.length() > 0)
++ doc.insertString(p0, content, a);
++ }
+ }
+ catch (BadLocationException e)
+ {
+- throw new AssertionError
+- ("No BadLocationException should be thrown here");
++ throw new AssertionError
++ ("No BadLocationException should be thrown here");
+ }
+ }
+
+Index: libjava/classpath/javax/swing/JEditorPane.java
+===================================================================
+--- libjava/classpath/javax/swing/JEditorPane.java (revision 111438)
++++ libjava/classpath/javax/swing/JEditorPane.java (working copy)
+@@ -43,8 +43,10 @@
+ import java.io.InputStream;
+ import java.io.InputStreamReader;
+ import java.io.Reader;
++import java.io.StringReader;
+ import java.net.MalformedURLException;
+ import java.net.URL;
++import java.util.HashMap;
+
+ import javax.accessibility.AccessibleContext;
+ import javax.accessibility.AccessibleHyperlink;
+@@ -88,6 +90,7 @@
+ *
+ * @author original author unknown
+ * @author Roman Kennke (roman@kennke.org)
++ * @author Anthony Balkissoon abalkiss at redhat dot com
+ */
+ public class JEditorPane extends JTextComponent
+ {
+@@ -168,6 +171,14 @@
+ {
+
+ /**
++ * Creates a new JEditorPaneAccessibleHypertextSupport object.
++ */
++ public JEditorPaneAccessibleHypertextSupport()
++ {
++ super();
++ }
++
++ /**
+ * The accessible representation of a HTML link.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+@@ -499,9 +510,16 @@
+ private EditorKit editorKit;
+
+ boolean focus_root;
++
++ // A mapping between content types and registered EditorKit types
++ static HashMap registerMap;
++
++ // A mapping between content types and used EditorKits
++ HashMap editorMap;
+
+ public JEditorPane()
+ {
++ init();
+ setEditorKit(createDefaultEditorKit());
+ }
+
+@@ -512,24 +530,69 @@
+
+ public JEditorPane(String type, String text)
+ {
++ init();
+ setEditorKit(createEditorKitForContentType(type));
+ setText(text);
+ }
+
+ public JEditorPane(URL url) throws IOException
+ {
+- this();
++ init ();
++ setEditorKit (createEditorKitForContentType("text/html"));;
+ setPage(url);
+ }
++
++ /**
++ * Called by the constructors to set up the default bindings for content
++ * types and EditorKits.
++ */
++ void init()
++ {
++ editorMap = new HashMap();
++ registerMap = new HashMap();
++ registerEditorKitForContentType("application/rtf",
++ "javax.swing.text.rtf.RTFEditorKit");
++ registerEditorKitForContentType("text/plain",
++ "javax.swing.JEditorPane$PlainEditorKit");
++ registerEditorKitForContentType("text/html",
++ "javax.swing.text.html.HTMLEditorKit");
++ registerEditorKitForContentType("text/rtf",
++ "javax.swing.text.rtf.RTFEditorKit");
++ }
+
+ protected EditorKit createDefaultEditorKit()
+ {
+ return new PlainEditorKit();
+ }
+
++ /**
++ * Creates and returns an EditorKit that is appropriate for the given
++ * content type. This is created using the default recognized types
++ * plus any EditorKit types that have been registered.
++ *
++ * @see #registerEditorKitForContentType(String, String)
++ * @see #registerEditorKitForContentType(String, String, ClassLoader)
++ * @param type the content type
++ * @return an EditorKit for use with the given content type
++ */
+ public static EditorKit createEditorKitForContentType(String type)
+ {
+- return new PlainEditorKit();
++ // TODO: Have to handle the case where a ClassLoader was specified
++ // when the EditorKit was registered
++ EditorKit e = null;
++ String className = (String)registerMap.get(type);
++ if (className != null)
++ {
++ try
++ {
++ e = (EditorKit) Class.forName(className).newInstance();
++ }
++ catch (Exception e2)
++ {
++ // TODO: Not sure what to do here.
++ }
++ }
++ return e;
+ }
+
+ /**
+@@ -578,14 +641,44 @@
+ return editorKit;
+ }
+
++ /**
++ * Returns the class name of the EditorKit associated with the given
++ * content type.
++ *
++ * @since 1.3
++ * @param type the content type
++ * @return the class name of the EditorKit associated with this content type
++ */
+ public static String getEditorKitClassNameForContentType(String type)
+ {
+- return "text/plain";
++ return (String) registerMap.get(type);
+ }
+
++ /**
++ * Returns the EditorKit to use for the given content type. If an
++ * EditorKit has been explicitly set via
++ * setEditorKitForContentType
++ * then it will be returned. Otherwise an attempt will be made to create
++ * an EditorKit from the default recognzied content types or any
++ * EditorKits that have been registered. If none can be created, a
++ * PlainEditorKit is created.
++ *
++ * @see #registerEditorKitForContentType(String, String)
++ * @see #registerEditorKitForContentType(String, String, ClassLoader)
++ * @param type the content type
++ * @return an appropriate EditorKit for the given content type
++ */
+ public EditorKit getEditorKitForContentType(String type)
+ {
+- return editorKit;
++ // First check if an EditorKit has been explicitly set.
++ EditorKit e = (EditorKit) editorMap.get(type);
++ // Then check to see if we can create one.
++ if (e == null)
++ e = createEditorKitForContentType(type);
++ // Otherwise default to PlainEditorKit.
++ if (e == null)
++ e = new PlainEditorKit();
++ return e;
+ }
+
+ /**
+@@ -669,12 +762,17 @@
+ }
+
+ /**
+- * Establishes the default bindings of type to classname.
++ * Establishes a binding between type and classname. This enables
++ * us to create an EditorKit later for the given content type.
++ *
++ * @param type the content type
++ * @param classname the name of the class that is associated with this
++ * content type
+ */
+ public static void registerEditorKitForContentType(String type,
+ String classname)
+ {
+- // TODO: Implement this properly.
++ registerMap.put(type, classname);
+ }
+
+ /**
+@@ -694,6 +792,7 @@
+ public void replaceSelection(String content)
+ {
+ // TODO: Implement this properly.
++ super.replaceSelection(content);
+ }
+
+ /**
+@@ -741,9 +840,14 @@
+ accessibleContext = null;
+ }
+
++ /**
++ * Explicitly sets an EditorKit to be used for the given content type.
++ * @param type the content type
++ * @param k the EditorKit to use for the given content type
++ */
+ public void setEditorKitForContentType(String type, EditorKit k)
+ {
+- // FIXME: editorKitCache.put(type, kit);
++ editorMap.put(type, k);
+ }
+
+ /**
+@@ -773,9 +877,36 @@
+ }
+ }
+
++ /**
++ * Sets the text of the JEditorPane. The argument t
++ * is expected to be in the format of the current EditorKit. This removes
++ * the content of the current document and uses the EditorKit to read in the
++ * new text. This allows the EditorKit to handle the String rather than just
++ * inserting in plain text.
++ *
++ * @param t the text to display in this JEditorPane
++ */
+ public void setText(String t)
+ {
+- super.setText(t);
++ try
++ {
++ // Remove the current content.
++ Document doc = getDocument();
++ doc.remove(0, doc.getLength());
++ if (t == null || t == "")
++ return;
++
++ // Let the EditorKit read the text into the Document.
++ getEditorKit().read(new StringReader(t), doc, 0);
++ }
++ catch (BadLocationException ble)
++ {
++ // TODO: Don't know what to do here.
++ }
++ catch (IOException ioe)
++ {
++ // TODO: Don't know what to do here.
++ }
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/JFormattedTextField.java
+===================================================================
+--- libjava/classpath/javax/swing/JFormattedTextField.java (revision 111438)
++++ libjava/classpath/javax/swing/JFormattedTextField.java (working copy)
+@@ -40,15 +40,21 @@
+
+ import java.awt.event.FocusEvent;
+ import java.io.Serializable;
++import java.text.DateFormat;
+ import java.text.Format;
++import java.text.NumberFormat;
+ import java.text.ParseException;
+ import java.util.Date;
+
++import javax.swing.text.AbstractDocument;
+ import javax.swing.text.DateFormatter;
+ import javax.swing.text.DefaultFormatter;
++import javax.swing.text.DefaultFormatterFactory;
+ import javax.swing.text.Document;
+ import javax.swing.text.DocumentFilter;
++import javax.swing.text.InternationalFormatter;
+ import javax.swing.text.NavigationFilter;
++import javax.swing.text.NumberFormatter;
+
+ /**
+ * A text field that makes use of a formatter to display and edit a specific
+@@ -62,6 +68,7 @@
+ * formatting of the value of the JFormattedTextField.
+ *
+ * @author Michael Koch
++ * @author Anthony Balkissoon abalkiss at redhat dot com
+ *
+ * @since 1.4
+ */
+@@ -85,58 +92,184 @@
+ //Do nothing here.
+ }
+
++ /**
++ * Clones the AbstractFormatter and removes the association to any
++ * particular JFormattedTextField.
++ *
++ * @return a clone of this formatter with no association to any particular
++ * JFormattedTextField
++ * @throws CloneNotSupportedException if the Object's class doesn't support
++ * the {@link Cloneable} interface
++ */
+ protected Object clone ()
+ throws CloneNotSupportedException
+ {
+- throw new InternalError ("not implemented");
++ // Clone this formatter.
++ AbstractFormatter newFormatter = (AbstractFormatter)super.clone();
++
++ // And remove the association to the JFormattedTextField.
++ newFormatter.textField = null;
++ return newFormatter;
+ }
+
++ /**
++ * Returns a custom set of Actions that this formatter supports. Should
++ * be subclassed by formatters that have a custom set of Actions.
++ *
++ * @return null
. Should be subclassed by formatters that want
++ * to install custom Actions on the JFormattedTextField.
++ */
+ protected Action[] getActions ()
+ {
+- return textField.getActions();
++ return null;
+ }
+
++ /**
++ * Gets the DocumentFilter for this formatter. Should be subclassed
++ * by formatters wishing to install a filter that oversees Document
++ * mutations.
++ *
++ * @return null
. Should be subclassed by formatters
++ * that want to restrict Document mutations.
++ */
+ protected DocumentFilter getDocumentFilter ()
+ {
+- throw new InternalError ("not implemented");
++ // Subclasses should override this if they want to install a
++ // DocumentFilter.
++ return null;
+ }
+
++ /**
++ * Returns the JFormattedTextField on which this formatter is
++ * currently installed.
++ *
++ * @return the JFormattedTextField on which this formatter is currently
++ * installed
++ */
+ protected JFormattedTextField getFormattedTextField ()
+ {
+ return textField;
+ }
+
++ /**
++ * Gets the NavigationFilter for this formatter. Should be subclassed
++ * by formatters (such as {@link DefaultFormatter}) that wish to
++ * restrict where the cursor can be placed within the text field.
++ *
++ * @return null
. Subclassed by formatters that want to restrict
++ * cursor location within the JFormattedTextField.
++ */
+ protected NavigationFilter getNavigationFilter ()
+ {
+- return textField.getNavigationFilter();
++ // This should be subclassed if the formatter wants to install
++ // a NavigationFilter on the JFormattedTextField.
++ return null;
+ }
+
++ /**
++ * Installs this formatter on the specified JFormattedTextField. This
++ * converts the current value to a displayable String and displays it,
++ * and installs formatter specific Actions from getActions
.
++ * It also installs a DocumentFilter and NavigationFilter on the
++ * JFormattedTextField.
++ *
++ * If there is a ParseException
this sets the text to an
++ * empty String and marks the text field in an invalid state.
++ *
++ * @param textField the JFormattedTextField on which to install this
++ * formatter
++ */
+ public void install(JFormattedTextField textField)
+ {
++ // Uninstall the current textfield.
+ if (this.textField != null)
+- uninstall();
++ uninstall();
+
+ this.textField = textField;
++
++ // Install some state on the text field, including display text,
++ // DocumentFilter, NavigationFilter, and formatter specific Actions.
++ if (textField != null)
++ {
++ try
++ {
++ // Set the text of the field.
++ textField.setText(valueToString(textField.getValue()));
++ Document doc = textField.getDocument();
++
++ // Set the DocumentFilter for the field's Document.
++ if (doc instanceof AbstractDocument)
++ ((AbstractDocument)doc).setDocumentFilter(getDocumentFilter());
++
++ // Set the NavigationFilter.
++ textField.setNavigationFilter(getNavigationFilter());
++
++ // Set the Formatter Actions
++ // FIXME: Have to add the actions from getActions()
++ }
++ catch (ParseException pe)
++ {
++ // Set the text to an empty String and mark the field as invalid.
++ textField.setText("");
++ setEditValid(false);
++ }
++ }
+ }
+
++ /**
++ * Clears the state installed on the JFormattedTextField by the formatter.
++ * This resets the DocumentFilter, NavigationFilter, and any additional
++ * Actions (returned by getActions()
).
++ */
+ public void uninstall ()
+ {
++ // Set the DocumentFilter for the field's Document.
++ Document doc = textField.getDocument();
++ if (doc instanceof AbstractDocument)
++ ((AbstractDocument)doc).setDocumentFilter(null);
++ textField.setNavigationFilter(null);
++ // FIXME: Have to remove the Actions from getActions()
+ this.textField = null;
+ }
+
++ /**
++ * Invoke this method when invalid values are entered. This forwards the
++ * call to the JFormattedTextField.
++ */
+ protected void invalidEdit ()
+ {
+ textField.invalidEdit();
+ }
+
++ /**
++ * This method updates the editValid
property of
++ * JFormattedTextField.
++ *
++ * @param valid the new state for the editValid
property
++ */
+ protected void setEditValid (boolean valid)
+ {
+ textField.editValid = valid;
+ }
+
++ /**
++ * Parses text
to return a corresponding Object.
++ *
++ * @param text the String to parse
++ * @return an Object that text
represented
++ * @throws ParseException if there is an error in the conversion
++ */
+ public abstract Object stringToValue (String text)
+ throws ParseException;
+
++ /**
++ * Returns a String to be displayed, based on the Object
++ * value
.
++ *
++ * @param value the Object from which to generate a String
++ * @return a String to be displayed
++ * @throws ParseException if there is an error in the conversion
++ */
+ public abstract String valueToString (Object value)
+ throws ParseException;
+ }
+@@ -155,88 +288,177 @@
+ public abstract AbstractFormatter getFormatter (JFormattedTextField tf);
+ }
+
+- static class FormatterFactoryWrapper extends AbstractFormatterFactory
+- {
+- AbstractFormatter formatter;
+-
+- public FormatterFactoryWrapper(AbstractFormatter formatter)
+- {
+- this.formatter = formatter;
+- }
+-
+- public AbstractFormatter getFormatter(JFormattedTextField tf)
+- {
+- return formatter;
+- }
+- }
+-
++ /** The possible focusLostBehavior options **/
+ public static final int COMMIT = 0;
+ public static final int COMMIT_OR_REVERT = 1;
+ public static final int REVERT = 2;
+ public static final int PERSIST = 3;
+
++ /** The most recent valid and committed value **/
+ private Object value;
++
++ /** The behaviour for when this text field loses focus **/
+ private int focusLostBehavior = COMMIT_OR_REVERT;
++
++ /** The formatter factory currently being used **/
+ private AbstractFormatterFactory formatterFactory;
++
++ /** The formatter currently being used **/
++ private AbstractFormatter formatter;
++
+ // Package-private to avoid an accessor method.
+ boolean editValid = true;
+
++ /**
++ * Creates a JFormattedTextField with no formatter factory.
++ * setValue
or setFormatterFactory
will
++ * properly configure this text field to edit a particular type
++ * of value.
++ */
+ public JFormattedTextField ()
+ {
+ this((AbstractFormatterFactory) null, null);
+ }
+
++ /**
++ * Creates a JFormattedTextField that can handle the specified Format.
++ * An appopriate AbstractFormatter and AbstractFormatterFactory will
++ * be created for the specified Format.
++ *
++ * @param format the Format that this JFormattedTextField should be able
++ * to handle
++ */
+ public JFormattedTextField (Format format)
+ {
+- throw new InternalError ("not implemented");
++ this ();
++ setFormatterFactory(getAppropriateFormatterFactory(format));
+ }
+
++ /**
++ * Creates a JFormattedTextField with the specified formatter. This will
++ * create a {@link DefaultFormatterFactory} with this formatter as the default
++ * formatter.
++ *
++ * @param formatter the formatter to use for this JFormattedTextField
++ */
+ public JFormattedTextField (AbstractFormatter formatter)
+ {
+- this(new FormatterFactoryWrapper(formatter), null);
++ this(new DefaultFormatterFactory (formatter));
+ }
+
++ /**
++ * Creates a JFormattedTextField with the specified formatter factory.
++ *
++ * @param factory the formatter factory to use for this JFormattedTextField
++ */
+ public JFormattedTextField (AbstractFormatterFactory factory)
+ {
+- this(factory, null);
++ setFormatterFactory(factory);
+ }
+
++ /**
++ * Creates a JFormattedTextField with the specified formatter factory and
++ * initial value.
++ *
++ * @param factory the initial formatter factory for this JFormattedTextField
++ * @param value the initial value for the text field
++ */
+ public JFormattedTextField (AbstractFormatterFactory factory, Object value)
+- {
+- this.formatterFactory = factory;
+- this.value = value;
++ {
++ setFormatterFactory(factory);
++ setValue(value);
+ }
+
++ /**
++ * Creates a JFormattedTextField with the specified value. This creates a
++ * formatter and formatterFactory that are appropriate for the value.
++ *
++ * @param value the initial value for this JFormattedTextField
++ */
+ public JFormattedTextField (Object value)
+ {
+- this.value = value;
++ setValue(value);
+ }
++
++ /**
++ * Returns an AbstractFormatterFactory that will give an appropriate
++ * AbstractFormatter for the given Format.
++ * @param format the Format to match with an AbstractFormatter.
++ * @return a DefaultFormatterFactory whose defaultFormatter is appropriate
++ * for the given Format.
++ */
++ private AbstractFormatterFactory getAppropriateFormatterFactory (Format format)
++ {
++ AbstractFormatter newFormatter;
++ if (format instanceof DateFormat)
++ newFormatter = new DateFormatter((DateFormat)format);
++ else if (format instanceof NumberFormat)
++ newFormatter = new NumberFormatter ((NumberFormat)format);
++ else
++ newFormatter = new InternationalFormatter(format);
++
++ return new DefaultFormatterFactory(newFormatter);
++ }
+
++ /**
++ * Forces the current value from the editor to be set as the current
++ * value. If there is no current formatted this has no effect.
++ *
++ * @throws ParseException if the formatter cannot format the current value
++ */
+ public void commitEdit ()
+ throws ParseException
+ {
+- throw new InternalError ("not implemented");
++ if (formatter == null)
++ return;
++ // Note: this code is a lot like setValue except that we don't want
++ // to create a new formatter.
++ Object oldValue = this.value;
++
++ this.value = formatter.stringToValue(getText());;
++ editValid = true;
++
++ firePropertyChange("value", oldValue, this.value);
+ }
+
++ /**
++ * Gets the command list supplied by the UI augmented by the specific
++ * Actions for JFormattedTextField.
++ *
++ * @return an array of Actions that this text field supports
++ */
+ public Action[] getActions ()
+ {
+ // FIXME: Add JFormattedTextField specific actions
++ // These are related to committing or cancelling edits.
+ return super.getActions();
+ }
+
++ /**
++ * Returns the behaviour of this JFormattedTextField upon losing focus. This
++ * is one of COMMIT
, COMMIT_OR_REVERT
,
++ * PERSIST
, or REVERT
.
++ * @return the behaviour upon losing focus
++ */
+ public int getFocusLostBehavior()
+ {
+ return focusLostBehavior;
+ }
+
++ /**
++ * Returns the current formatter used for this JFormattedTextField.
++ * @return the current formatter used for this JFormattedTextField
++ */
+ public AbstractFormatter getFormatter ()
+ {
+- if (formatterFactory == null)
+- return null;
+-
+- return formatterFactory.getFormatter(this);
++ return formatter;
+ }
+-
++
++ /**
++ * Returns the factory currently used to generate formatters for this
++ * JFormattedTextField.
++ * @return the factory currently used to generate formatters
++ */
+ public AbstractFormatterFactory getFormatterFactory ()
+ {
+ return formatterFactory;
+@@ -247,31 +469,61 @@
+ return "FormattedTextFieldUI";
+ }
+
++ /**
++ * Returns the last valid value. This may not be the value currently shown
++ * in the text field depending on whether or not the formatter commits on
++ * valid edits and allows invalid input to be temporarily displayed.
++ * @return the last committed valid value
++ */
+ public Object getValue ()
+ {
+ return value;
+ }
+
++ /**
++ * This method is used to provide feedback to the user when an invalid value
++ * is input during editing.
++ */
+ protected void invalidEdit ()
+ {
+ UIManager.getLookAndFeel().provideErrorFeedback(this);
+ }
+
++ /**
++ * Returns true if the current value being edited is valid. This property is
++ * managed by the current formatted.
++ * @return true if the value being edited is valid.
++ */
+ public boolean isEditValid ()
+ {
+ return editValid;
+ }
+
++ /**
++ * Processes focus events. This is overridden because we may want to
++ * change the formatted depending on whether or not this field has
++ * focus.
++ *
++ * @param evt the FocusEvent
++ */
+ protected void processFocusEvent (FocusEvent evt)
+ {
+- // it's safe to simply call super for now, until it gets clear
+- // what this method is supposed to do
+- // throw new InternalError ("not implemented");
+ super.processFocusEvent(evt);
++ // Let the formatterFactory change the formatter for this text field
++ // based on whether or not it has focus.
++ setFormatter (formatterFactory.getFormatter(this));
+ }
+-
++
++ /**
++ * Associates this JFormattedTextField with a Document and propagates
++ * a PropertyChange event to each listener.
++ *
++ * @param newDocument the Document to associate with this text field
++ */
+ public void setDocument(Document newDocument)
+ {
++ // FIXME: This method should do more than this. Must do some handling
++ // of the DocumentListeners.
+ Document oldDocument = getDocument();
+
+ if (oldDocument == newDocument)
+@@ -280,6 +532,16 @@
+ super.setDocument(newDocument);
+ }
+
++ /**
++ * Sets the behaviour of this JFormattedTextField upon losing focus.
++ * This must be COMMIT
, COMMIT_OR_REVERT
,
++ * PERSIST
, or REVERT
or an
++ * IllegalArgumentException will be thrown.
++ *
++ * @param behavior
++ * @throws IllegalArgumentException if behaviour
is not
++ * one of the above
++ */
+ public void setFocusLostBehavior(int behavior)
+ {
+ if (behavior != COMMIT
+@@ -291,20 +553,38 @@
+ this.focusLostBehavior = behavior;
+ }
+
++ /**
++ * Sets the formatter for this JFormattedTextField. Normally the formatter
++ * factory will take care of this, or calls to setValue will also make sure
++ * that the formatter is set appropriately.
++ *
++ * @param formatter the AbstractFormatter to use for formatting the value for
++ * this JFormattedTextField
++ */
+ protected void setFormatter (AbstractFormatter formatter)
+ {
+ AbstractFormatter oldFormatter = null;
+
+- if (formatterFactory != null)
+- oldFormatter = formatterFactory.getFormatter(this);
++ oldFormatter = this.formatter;
+
+- if (oldFormatter == formatter)
+- return;
++ if (oldFormatter != null)
++ oldFormatter.uninstall();
++
++ this.formatter = formatter;
++
++ if (formatter != null)
++ formatter.install(this);
+
+- setFormatterFactory(new FormatterFactoryWrapper(formatter));
+ firePropertyChange("formatter", oldFormatter, formatter);
+ }
+
++ /**
++ * Sets the factory from which this JFormattedTextField should obtain
++ * its formatters.
++ *
++ * @param factory the AbstractFormatterFactory that will be used to generate
++ * formatters for this JFormattedTextField
++ */
+ public void setFormatterFactory (AbstractFormatterFactory factory)
+ {
+ if (formatterFactory == factory)
+@@ -313,55 +593,56 @@
+ AbstractFormatterFactory oldFactory = formatterFactory;
+ formatterFactory = factory;
+ firePropertyChange("formatterFactory", oldFactory, factory);
++
++ // Now set the formatter according to our new factory.
++ if (formatterFactory != null)
++ setFormatter(formatterFactory.getFormatter(this));
++ else
++ setFormatter(null);
+ }
+
++ /**
++ * Sets the value that will be formatted and displayed.
++ *
++ * @param newValue the value to be formatted and displayed
++ */
+ public void setValue (Object newValue)
+ {
+ if (value == newValue)
+ return;
+
+- // format value
+- AbstractFormatter formatter = createFormatter(newValue);
+- try
+- {
+- setText(formatter.valueToString(newValue));
+- }
+- catch (ParseException ex)
+- {
+- // TODO: what should we do with this?
+- }
+-
+ Object oldValue = value;
+ value = newValue;
++
++ // If there is no formatterFactory then make one.
++ if (formatterFactory == null)
++ setFormatterFactory(createFormatterFactory(newValue));
++
++ // Set the formatter appropriately. This is because there may be a new
++ // formatterFactory from the line above, or we may want a new formatter
++ // depending on the type of newValue (or if newValue is null).
++ setFormatter (formatterFactory.getFormatter(this));
+ firePropertyChange("value", oldValue, newValue);
+ }
+
+ /**
+- * A helper method that attempts to create a formatter that is suitable
+- * to format objects of the type like value
.
++ * A helper method that attempts to create a formatter factory that is
++ * suitable to format objects of the type like value
.
+ *
+- * If formatterFactory
is not null and the returned formatter
+- * is also not null
then this formatter is used. Otherwise we
+- * try to create one based on the type of value
.
++ * @param value an object which should be formatted by the formatter factory.
+ *
+- * @param value an object which should be formatted by the formatter
+- *
+- * @return a formatter able to format objects of the class of
++ * @return a formatter factory able to format objects of the class of
+ * value
+ */
+- AbstractFormatter createFormatter(Object value)
++ AbstractFormatterFactory createFormatterFactory(Object value)
+ {
+ AbstractFormatter formatter = null;
+- if (formatterFactory != null
+- && formatterFactory.getFormatter(this) != null)
+- formatter = formatterFactory.getFormatter(this);
+- else
+- {
+- if (value instanceof Date)
+- formatter = new DateFormatter();
+- else
+- formatter = new DefaultFormatter();
+- }
+- return formatter;
++ if (value instanceof Date)
++ formatter = new DateFormatter();
++ else if (value instanceof Number)
++ formatter = new NumberFormatter();
++ else
++ formatter = new DefaultFormatter();
++ return new DefaultFormatterFactory(formatter);
+ }
+ }
+Index: libjava/classpath/javax/swing/JTree.java
+===================================================================
+--- libjava/classpath/javax/swing/JTree.java (revision 111438)
++++ libjava/classpath/javax/swing/JTree.java (working copy)
+@@ -1481,6 +1481,7 @@
+ setRootVisible(true);
+ setModel(model);
+ setSelectionModel(new EmptySelectionModel());
++ selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/tree/DefaultTreeModel.java
+===================================================================
+--- libjava/classpath/javax/swing/tree/DefaultTreeModel.java (revision 111438)
++++ libjava/classpath/javax/swing/tree/DefaultTreeModel.java (working copy)
+@@ -148,12 +148,6 @@
+ */
+ public void setRoot(TreeNode root)
+ {
+- // Sanity Check
+- if (root == null)
+- {
+- throw new IllegalArgumentException("null root");
+- }
+- // Set new root
+ this.root = root;
+ }
+
+Index: libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java
+===================================================================
+--- libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java (revision 111438)
++++ libjava/classpath/javax/swing/tree/DefaultTreeSelectionModel.java (working copy)
+@@ -116,7 +116,7 @@
+ */
+ public DefaultTreeSelectionModel()
+ {
+- setSelectionMode(SINGLE_TREE_SELECTION);
++ setSelectionMode(DISCONTIGUOUS_TREE_SELECTION);
+ listenerList = new EventListenerList();
+ }
+
+Index: libjava/classpath/javax/swing/LookAndFeel.java
+===================================================================
+--- libjava/classpath/javax/swing/LookAndFeel.java (revision 111438)
++++ libjava/classpath/javax/swing/LookAndFeel.java (working copy)
+@@ -300,11 +300,11 @@
+ /**
+ * Returns a string that displays and identifies this object's properties.
+ *
+- * @return the string "LookAndFeel"
++ * @return string containing the description and class name.
+ */
+ public String toString()
+ {
+- return "LookAndFeel";
++ return getDescription() + " " + getClass().getName();
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/JList.java
+===================================================================
+--- libjava/classpath/javax/swing/JList.java (revision 111438)
++++ libjava/classpath/javax/swing/JList.java (working copy)
+@@ -1070,14 +1070,16 @@
+ layoutOrientation = VERTICAL;
+ opaque = true;
+ valueIsAdjusting = false;
+- visibleRowCount = 8;
++ visibleRowCount = 7;
+
+ cellRenderer = new DefaultListCellRenderer();
+ listListener = new ListListener();
+
+ setModel(new DefaultListModel());
+ setSelectionModel(createSelectionModel());
+-
++ setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
++ setLayout(null);
++
+ updateUI();
+ }
+
+@@ -1255,14 +1257,17 @@
+ *
+ * @param a A number in the half-open range [0, x)
where
+ * x = getModel.getSize()
, indicating the index of an
+- * element in the list to select.
++ * element in the list to select. When < 0 the selection is cleared.
+ *
+ * @see #setSelectionMode
+ * @see #selectionModel
+ */
+ public void setSelectedIndex(int a)
+ {
+- selectionModel.setSelectionInterval(a, a);
++ if (a < 0)
++ selectionModel.clearSelection();
++ else
++ selectionModel.setSelectionInterval(a, a);
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/Popup.java
+===================================================================
+--- libjava/classpath/javax/swing/Popup.java (revision 111438)
++++ libjava/classpath/javax/swing/Popup.java (working copy)
+@@ -41,6 +41,7 @@
+ import java.awt.Component;
+ import java.awt.FlowLayout;
+ import java.awt.Point;
++import java.awt.Rectangle;
+
+
+ /**
+@@ -291,7 +292,9 @@
+ */
+ public void hide()
+ {
++ Rectangle bounds = panel.getBounds();
+ layeredPane.remove(panel);
++ layeredPane.repaint(bounds.x, bounds.y, bounds.width, bounds.height);
+ }
+ }
+ }
+Index: libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java
+===================================================================
+--- libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java (revision 111438)
++++ libjava/classpath/javax/swing/table/DefaultTableCellRenderer.java (working copy)
+@@ -181,7 +181,6 @@
+ else
+ setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
+
+- setEnabled(table.isEnabled());
+ setFont(table.getFont());
+
+ // If the current background is equal to the table's background, then we
+Index: libjava/classpath/javax/swing/TransferHandler.java
+===================================================================
+--- libjava/classpath/javax/swing/TransferHandler.java (revision 111438)
++++ libjava/classpath/javax/swing/TransferHandler.java (working copy)
+@@ -1,5 +1,5 @@
+ /* TransferHandler.java --
+- Copyright (C) 2004 Free Software Foundation, Inc.
++ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+@@ -43,6 +43,7 @@
+ import java.awt.datatransfer.Transferable;
+ import java.awt.event.ActionEvent;
+ import java.awt.event.InputEvent;
++import java.awt.Toolkit;
+ import java.io.Serializable;
+
+ public class TransferHandler implements Serializable
+@@ -53,6 +54,7 @@
+
+ public TransferAction(String command)
+ {
++ super(command);
+ this.command = command;
+ }
+
+@@ -62,6 +64,13 @@
+ TransferHandler transferHandler = component.getTransferHandler();
+ Clipboard clipboard = getClipboard(component);
+
++ if (clipboard == null)
++ {
++ // Access denied!
++ Toolkit.getDefaultToolkit().beep();
++ return;
++ }
++
+ if (command.equals(COMMAND_COPY))
+ transferHandler.exportToClipboard(component, clipboard, COPY);
+ else if (command.equals(COMMAND_CUT))
+@@ -76,37 +85,22 @@
+ }
+
+ /**
+- * Get the system cliboard. If not available, create and return the VM-local
+- * clipboard.
++ * Get the system cliboard or null if the caller isn't allowed to
++ * access the system clipboard.
+ *
+ * @param component a component, used to get the toolkit.
+ * @return the clipboard
+ */
+ private static Clipboard getClipboard(JComponent component)
+ {
+- // Avoid throwing exception if the system clipboard access failed
+- // in the past.
+- if (clipboard != null)
+- return clipboard;
+- else
+- {
+- try
+- {
+- SecurityManager sm = System.getSecurityManager();
+- if (sm != null)
+- sm.checkSystemClipboardAccess();
+-
+- // We may access system clipboard.
+- return component.getToolkit().getSystemClipboard();
+- }
+- catch (Exception e)
+- {
+- // We may not access system clipboard.
+- // Create VM-local clipboard if none exists yet.
+- clipboard = new Clipboard("Clipboard");
+- return clipboard;
+- }
+- }
++ try
++ {
++ return component.getToolkit().getSystemClipboard();
++ }
++ catch (SecurityException se)
++ {
++ return null;
++ }
+ }
+ }
+
+@@ -125,12 +119,6 @@
+ private static Action cutAction = new TransferAction(COMMAND_CUT);
+ private static Action pasteAction = new TransferAction(COMMAND_PASTE);
+
+- /**
+- * Clipboard if system clipboard may not be used.
+- * Package-private to avoid an accessor method.
+- */
+- static Clipboard clipboard;
+-
+ private int sourceActions;
+ private Icon visualRepresentation;
+
+Index: libjava/classpath/javax/swing/BoxLayout.java
+===================================================================
+--- libjava/classpath/javax/swing/BoxLayout.java (revision 111438)
++++ libjava/classpath/javax/swing/BoxLayout.java (working copy)
+@@ -335,8 +335,15 @@
+
+ checkTotalRequirements();
+ Insets i = container.getInsets();
+- return new Dimension(xTotal.maximum + i.left + i.right,
+- yTotal.maximum + i.top + i.bottom);
++ int xDim = xTotal.maximum + i.left + i.right;
++ int yDim = yTotal.maximum + i.top + i.bottom;
++
++ // Check for overflow
++ if (xDim < xTotal.maximum)
++ xDim = Integer.MAX_VALUE;
++ if (yDim < yTotal.maximum)
++ yDim = Integer.MAX_VALUE;
++ return new Dimension(xDim, yDim);
+ }
+ }
+
+Index: libjava/classpath/javax/swing/JTextField.java
+===================================================================
+--- libjava/classpath/javax/swing/JTextField.java (revision 111438)
++++ libjava/classpath/javax/swing/JTextField.java (working copy)
+@@ -203,9 +203,22 @@
+ */
+ protected Document createDefaultModel()
+ {
+- PlainDocument doc = new PlainDocument();
++ return new PlainDocument();
++ }
++
++ /**
++ * Sets the document to be used for this JTextField.
++ *
++ * This sets the document property filterNewlines
to
++ * true
and then calls the super behaviour to setup a view and
++ * revalidate the text field.
++ *
++ * @param doc the document to set
++ */
++ public void setDocument(Document doc)
++ {
+ doc.putProperty("filterNewlines", Boolean.TRUE);
+- return doc;
++ super.setDocument(doc);
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/JLayeredPane.java
+===================================================================
+--- libjava/classpath/javax/swing/JLayeredPane.java (revision 111438)
++++ libjava/classpath/javax/swing/JLayeredPane.java (working copy)
+@@ -436,7 +436,12 @@
+ // should have found it
+ throw new IllegalArgumentException();
+
+- super.swapComponents (curr, targ);
++ if (curr == 0)
++ super.swapComponents(curr, targ);
++ else
++ while (curr > 0)
++ super.swapComponents (curr, --curr);
++
+ revalidate();
+ repaint();
+ }
+Index: libjava/classpath/javax/swing/text/AbstractDocument.java
+===================================================================
+--- libjava/classpath/javax/swing/text/AbstractDocument.java (revision 111438)
++++ libjava/classpath/javax/swing/text/AbstractDocument.java (working copy)
+@@ -541,6 +541,9 @@
+
+ writeLock();
+ UndoableEdit undo = content.insertString(offset, text);
++ if (undo != null)
++ event.addEdit(undo);
++
+ insertUpdate(event, attributes);
+ writeUnlock();
+
+@@ -1326,7 +1329,14 @@
+ */
+ public Object getAttribute(Object key)
+ {
+- return attributes.getAttribute(key);
++ Object result = attributes.getAttribute(key);
++ if (result == null && element_parent != null)
++ {
++ AttributeSet parentSet = element_parent.getAttributes();
++ if (parentSet != null)
++ result = parentSet.getAttribute(key);
++ }
++ return result;
+ }
+
+ /**
+@@ -1809,6 +1819,12 @@
+ Hashtable changes;
+
+ /**
++ * Indicates if this event has been modified or not. This is used to
++ * determine if this event is thrown.
++ */
++ boolean modified;
++
++ /**
+ * Creates a new DefaultDocumentEvent
.
+ *
+ * @param offset the starting offset of the change
+@@ -1822,6 +1838,7 @@
+ this.length = length;
+ this.type = type;
+ changes = new Hashtable();
++ modified = false;
+ }
+
+ /**
+@@ -1836,6 +1853,7 @@
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ if (edit instanceof DocumentEvent.ElementChange)
+ {
++ modified = true;
+ DocumentEvent.ElementChange elEdit =
+ (DocumentEvent.ElementChange) edit;
+ changes.put(elEdit.getElement(), elEdit);
+@@ -1896,6 +1914,15 @@
+ // XXX - Fully qualify ElementChange to work around gcj bug #2499.
+ return (DocumentEvent.ElementChange) changes.get(elem);
+ }
++
++ /**
++ * Returns a String description of the change event. This returns the
++ * toString method of the Vector of edits.
++ */
++ public String toString()
++ {
++ return edits.toString();
++ }
+ }
+
+ /**
+Index: libjava/classpath/javax/swing/text/PlainDocument.java
+===================================================================
+--- libjava/classpath/javax/swing/text/PlainDocument.java (revision 111438)
++++ libjava/classpath/javax/swing/text/PlainDocument.java (working copy)
+@@ -113,6 +113,46 @@
+ int elementIndex = rootElement.getElementIndex(offset);
+ Element firstElement = rootElement.getElement(elementIndex);
+
++ // If we're inserting immediately after a newline we have to fix the
++ // Element structure.
++ if (offset > 0)
++ {
++ try
++ {
++ String s = getText(offset - 1, 1);
++ if (s.equals("\n"))
++ {
++ int newEl2EndOffset = end;
++ boolean replaceNext = false;
++ if (rootElement.getElementCount() > elementIndex + 1)
++ {
++ replaceNext = true;
++ newEl2EndOffset =
++ rootElement.getElement(elementIndex + 1).getEndOffset();
++ }
++ Element newEl1 =
++ createLeafElement(rootElement, firstElement.getAttributes(),
++ firstElement.getStartOffset(), offset);
++ Element newEl2 =
++ createLeafElement (rootElement, firstElement.getAttributes(),
++ offset, newEl2EndOffset);
++ if (replaceNext)
++ rootElement.replace(elementIndex, 2, new Element[] { newEl1, newEl2 });
++ else
++ rootElement.replace(elementIndex, 1, new Element[] { newEl1, newEl2 });
++ firstElement = newEl2;
++ elementIndex ++;
++ }
++ }
++ catch (BadLocationException ble)
++ {
++ // This shouldn't happen.
++ AssertionError ae = new AssertionError();
++ ae.initCause(ble);
++ throw ae;
++ }
++ }
++
+ // added and removed are Element arrays used to add an ElementEdit
+ // to the DocumentEvent if there were entire lines added or removed.
+ Element[] removed = new Element[1];
+Index: libjava/classpath/javax/swing/text/DefaultStyledDocument.java
+===================================================================
+--- libjava/classpath/javax/swing/text/DefaultStyledDocument.java (revision 111438)
++++ libjava/classpath/javax/swing/text/DefaultStyledDocument.java (working copy)
+@@ -42,11 +42,13 @@
+ import java.awt.Font;
+ import java.io.Serializable;
+ import java.util.Enumeration;
++import java.util.Stack;
+ import java.util.Vector;
+
+ import javax.swing.event.ChangeEvent;
+ import javax.swing.event.ChangeListener;
+ import javax.swing.event.DocumentEvent;
++import javax.swing.event.UndoableEditEvent;
+ import javax.swing.undo.AbstractUndoableEdit;
+ import javax.swing.undo.UndoableEdit;
+
+@@ -365,7 +367,6 @@
+ public String toString()
+ {
+ StringBuilder b = new StringBuilder();
+- b.append('<');
+ switch (type)
+ {
+ case StartTagType:
+@@ -427,8 +428,31 @@
+
+ /** Holds the length of structural changes. */
+ private int length;
++
++ /** Holds the end offset for structural changes. **/
++ private int endOffset;
+
+ /**
++ * The number of inserted end tags. This is a counter which always gets
++ * incremented when an end tag is inserted. This is evaluated before
++ * content insertion to go up the element stack.
++ */
++ private int numEndTags;
++
++ /**
++ * The number of inserted start tags. This is a counter which always gets
++ * incremented when an end tag is inserted. This is evaluated before
++ * content insertion to go up the element stack.
++ */
++ private int numStartTags;
++
++ /**
++ * The current position in the element tree. This is used for bulk inserts
++ * using ElementSpecs.
++ */
++ private Stack elementStack;
++
++ /**
+ * Holds fractured elements during insertion of end and start tags.
+ * Inserting an end tag may lead to fracturing of the current paragraph
+ * element. The elements that have been cut off may be added to the
+@@ -450,6 +474,7 @@
+ public ElementBuffer(Element root)
+ {
+ this.root = root;
++ elementStack = new Stack();
+ }
+
+ /**
+@@ -463,6 +488,85 @@
+ }
+
+ /**
++ * Updates the element structure of the document in response to removal of
++ * content. It removes the affected {@link Element}s from the document
++ * structure.
++ *
++ * This method sets some internal parameters and delegates the work
++ * to {@link #removeUpdate}.
++ *
++ * @param offs the offset from which content is remove
++ * @param len the length of the removed content
++ * @param ev the document event that records the changes
++ */
++ public void remove(int offs, int len, DefaultDocumentEvent ev)
++ {
++ offset = offs;
++ length = len;
++ documentEvent = ev;
++ removeUpdate();
++ }
++
++ /**
++ * Updates the element structure of the document in response to removal of
++ * content. It removes the affected {@link Element}s from the document
++ * structure.
++ */
++ protected void removeUpdate()
++ {
++ int startParagraph = root.getElementIndex(offset);
++ int endParagraph = root.getElementIndex(offset + length);
++ Element[] empty = new Element[0];
++ int removeStart = -1;
++ int removeEnd = -1;
++ for (int i = startParagraph; i < endParagraph; i++)
++ {
++ Element paragraph = root.getElement(i);
++ int contentStart = paragraph.getElementIndex(offset);
++ int contentEnd = paragraph.getElementIndex(offset + length);
++ if (contentStart == paragraph.getStartOffset()
++ && contentEnd == paragraph.getEndOffset())
++ {
++ // In this case we only need to remove the whole paragraph. We
++ // do this in one go after this loop and only record the indices
++ // here.
++ if (removeStart == -1)
++ {
++ removeStart = i;
++ removeEnd = i;
++ }
++ else
++ removeEnd = i;
++ }
++ else
++ {
++ // In this case we remove a couple of child elements from this
++ // paragraph.
++ int removeLen = contentEnd - contentStart;
++ Element[] removed = new Element[removeLen];
++ for (int j = contentStart; j < contentEnd; j++)
++ removed[j] = paragraph.getElement(j);
++ ((BranchElement) paragraph).replace(contentStart, removeLen,
++ empty);
++ documentEvent.addEdit(new ElementEdit(paragraph, contentStart,
++ removed, empty));
++ }
++ }
++ // Now we remove paragraphs from the root that have been tagged for
++ // removal.
++ if (removeStart != -1)
++ {
++ int removeLen = removeEnd - removeStart;
++ Element[] removed = new Element[removeLen];
++ for (int i = removeStart; i < removeEnd; i++)
++ removed[i] = root.getElement(i);
++ ((BranchElement) root).replace(removeStart, removeLen, empty);
++ documentEvent.addEdit(new ElementEdit(root, removeStart, removed,
++ empty));
++ }
++ }
++
++ /**
+ * Modifies the element structure so that the specified interval starts
+ * and ends at an element boundary. Content and paragraph elements
+ * are split and created as necessary.
+@@ -493,11 +597,50 @@
+ {
+ // Split up the element at the start offset if necessary.
+ Element el = getCharacterElement(offset);
+- split(el, offset);
++ Element[] res = split(el, offset, 0);
++ BranchElement par = (BranchElement) el.getParentElement();
++ if (res[1] != null)
++ {
++ int index = par.getElementIndex(offset);
++ Element[] removed;
++ Element[] added;
++ if (res[0] == null)
++ {
++ removed = new Element[0];
++ added = new Element[]{ res[1] };
++ index++;
++ }
++ else
++ {
++ removed = new Element[]{ el };
++ added = new Element[]{ res[0], res[1] };
++ }
++ par.replace(index, removed.length, added);
++ addEdit(par, index, removed, added);
++ }
+
+ int endOffset = offset + length;
+ el = getCharacterElement(endOffset);
+- split(el, endOffset);
++ res = split(el, endOffset, 0);
++ par = (BranchElement) el.getParentElement();
++ if (res[1] != null)
++ {
++ int index = par.getElementIndex(offset);
++ Element[] removed;
++ Element[] added;
++ if (res[1] == null)
++ {
++ removed = new Element[0];
++ added = new Element[]{ res[1] };
++ }
++ else
++ {
++ removed = new Element[]{ el };
++ added = new Element[]{ res[0], res[1] };
++ }
++ par.replace(index, removed.length, added);
++ addEdit(par, index, removed, added);
++ }
+ }
+
+ /**
+@@ -505,42 +648,96 @@
+ *
+ * @param el the Element to possibly split
+ * @param offset the offset at which to possibly split
++ * @param space the amount of space to create between the splitted parts
++ *
++ * @return An array of elements which represent the split result. This
++ * array has two elements, the two parts of the split. The first
++ * element might be null, which means that the element which should
++ * be splitted can remain in place. The second element might also
++ * be null, which means that the offset is already at an element
++ * boundary and the element doesn't need to be splitted.
++ *
+ */
+- void split(Element el, int offset)
++ private Element[] split(Element el, int offset, int space)
+ {
+- if (el instanceof AbstractElement)
++ // If we are at an element boundary, then return an empty array.
++ if ((offset == el.getStartOffset() || offset == el.getEndOffset())
++ && space == 0 && el.isLeaf())
++ return new Element[2];
++
++ // If the element is an instance of BranchElement, then we recursivly
++ // call this method to perform the split.
++ Element[] res = new Element[2];
++ if (el instanceof BranchElement)
+ {
+- AbstractElement ael = (AbstractElement) el;
+- int startOffset = ael.getStartOffset();
+- int endOffset = ael.getEndOffset();
+- int len = endOffset - startOffset;
+- if (startOffset != offset && endOffset != offset)
++ int index = el.getElementIndex(offset);
++ Element child = el.getElement(index);
++ Element[] result = split(child, offset, space);
++ Element[] removed;
++ Element[] added;
++ Element[] newAdded;
++
++ int count = el.getElementCount();
++ if (!(result[1] == null))
+ {
+- Element paragraph = ael.getParentElement();
+- if (paragraph instanceof BranchElement)
++ // This is the case when we can keep the first element.
++ if (result[0] == null)
+ {
+- BranchElement par = (BranchElement) paragraph;
+- Element child1 = createLeafElement(par, ael, startOffset,
+- offset);
+- Element child2 = createLeafElement(par, ael, offset,
+- endOffset);
+- int index = par.getElementIndex(startOffset);
+- Element[] add = new Element[]{ child1, child2 };
+- par.replace(index, 1, add);
+- documentEvent.addEdit(new ElementEdit(par, index,
+- new Element[]{ el },
+- add));
++ removed = new Element[count - index - 1];
++ newAdded = new Element[count - index - 1];
++ added = new Element[]{};
+ }
++ // This is the case when we may not keep the first element.
+ else
+- throw new AssertionError("paragraph elements are expected to "
+- + "be instances of "
+- + "javax.swing.text.AbstractDocument.BranchElement");
++ {
++ removed = new Element[count - index];
++ newAdded = new Element[count - index];
++ added = new Element[]{result[0]};
++ }
++ newAdded[0] = result[1];
++ for (int i = index; i < count; i++)
++ {
++ Element el2 = el.getElement(i);
++ int ind = i - count + removed.length;
++ removed[ind] = el2;
++ if (ind != 0)
++ newAdded[ind] = el2;
++ }
++
++ ((BranchElement) el).replace(index, removed.length, added);
++ addEdit(el, index, removed, added);
++ BranchElement newPar =
++ (BranchElement) createBranchElement(el.getParentElement(),
++ el.getAttributes());
++ newPar.replace(0, 0, newAdded);
++ res = new Element[]{ null, newPar };
+ }
++ else
++ {
++ removed = new Element[count - index];
++ for (int i = index; i < count; ++i)
++ removed[i - index] = el.getElement(i);
++ added = new Element[0];
++ ((BranchElement) el).replace(index, removed.length,
++ added);
++ addEdit(el, index, removed, added);
++ BranchElement newPar =
++ (BranchElement) createBranchElement(el.getParentElement(),
++ el.getAttributes());
++ newPar.replace(0, 0, removed);
++ res = new Element[]{ null, newPar };
++ }
+ }
+- else
+- throw new AssertionError("content elements are expected to be "
+- + "instances of "
+- + "javax.swing.text.AbstractDocument.AbstractElement");
++ else if (el instanceof LeafElement)
++ {
++ BranchElement par = (BranchElement) el.getParentElement();
++ Element el1 = createLeafElement(par, el.getAttributes(),
++ el.getStartOffset(), offset);
++ Element el2 = createLeafElement(par, el.getAttributes(),
++ offset + space, el.getEndOffset());
++ res = new Element[]{ el1, el2 };
++ }
++ return res;
+ }
+
+ /**
+@@ -560,9 +757,18 @@
+ public void insert(int offset, int length, ElementSpec[] data,
+ DefaultDocumentEvent ev)
+ {
++ if (length == 0)
++ return;
+ this.offset = offset;
+ this.length = length;
++ this.endOffset = offset + length;
+ documentEvent = ev;
++ // Push the root and the paragraph at offset onto the element stack.
++ elementStack.clear();
++ elementStack.push(root);
++ elementStack.push(root.getElement(root.getElementIndex(offset)));
++ numEndTags = 0;
++ numStartTags = 0;
+ insertUpdate(data);
+ }
+
+@@ -573,202 +779,348 @@
+ * {@link #insert}.
+ *
+ * @param data the element specifications for the elements to be inserte
+- */
++ */
+ protected void insertUpdate(ElementSpec[] data)
+ {
++ if (data[0].getType() == ElementSpec.EndTagType)
++ {
++ // fracture deepest child here
++ BranchElement paragraph = (BranchElement) elementStack.peek();
++ Element curr = paragraph.getParentElement();
++ int index = curr.getElementIndex(offset);
++ while (!curr.isLeaf())
++ {
++ index = curr.getElementIndex(offset);
++ curr = curr.getElement(index);
++ }
++ Element parent = curr.getParentElement();
++ Element newEl1 = createLeafElement(parent,
++ curr.getAttributes(),
++ curr.getStartOffset(), offset);
++ Element grandParent = parent.getParentElement();
++ BranchElement nextBranch =
++ (BranchElement) grandParent.getElement
++ (grandParent.getElementIndex(parent.getEndOffset()));
++ Element firstLeaf = nextBranch.getElement(0);
++ while (!firstLeaf.isLeaf())
++ {
++ firstLeaf = firstLeaf.getElement(0);
++ }
++ BranchElement parent2 = (BranchElement) firstLeaf.getParentElement();
++ Element newEl2 =
++ createLeafElement(parent2,
++ firstLeaf.getAttributes(),
++ offset, firstLeaf.getEndOffset());
++ parent2.replace(0, 1, new Element[] { newEl2 });
++
++
++ ((BranchElement) parent).
++ replace(index, 1, new Element[] { newEl1 });
++ }
++
+ for (int i = 0; i < data.length; i++)
+ {
++ BranchElement paragraph = (BranchElement) elementStack.peek();
+ switch (data[i].getType())
+ {
+ case ElementSpec.StartTagType:
+- insertStartTag(data[i]);
++ switch (data[i].getDirection())
++ {
++ case ElementSpec.JoinFractureDirection:
++ insertFracture(data[i]);
++ break;
++ case ElementSpec.JoinNextDirection:
++ int index = paragraph.getElementIndex(offset);
++ elementStack.push(paragraph.getElement(index));
++ break;
++ case ElementSpec.OriginateDirection:
++ Element current = (Element) elementStack.peek();
++ Element newParagraph =
++ insertParagraph((BranchElement) current, offset);
++ elementStack.push(newParagraph);
++ break;
++ default:
++ break;
++ }
+ break;
+ case ElementSpec.EndTagType:
+- insertEndTag(data[i]);
++ elementStack.pop();
+ break;
+- default:
++ case ElementSpec.ContentType:
+ insertContentTag(data[i]);
+ break;
+ }
+ }
++ endEdit();
+ }
+
+ /**
+- * Insert a new paragraph after the paragraph at the current position.
+- *
+- * @param tag the element spec that describes the element to be inserted
++ * Finishes an insertion by possibly evaluating the outstanding start and
++ * end tags. However, this is only performed if the event has received any
++ * modifications.
+ */
+- void insertStartTag(ElementSpec tag)
++ private void endEdit()
+ {
+- BranchElement root = (BranchElement) getDefaultRootElement();
+- int index = root.getElementIndex(offset);
+- if (index == -1)
+- index = 0;
++ if (documentEvent.modified)
++ prepareContentInsertion();
++ }
+
+- BranchElement newParagraph =
+- (BranchElement) createBranchElement(root, tag.getAttributes());
+- newParagraph.setResolveParent(getStyle(StyleContext.DEFAULT_STYLE));
++ /**
++ * Evaluates the number of inserted end tags and performs the corresponding
++ * structural changes.
++ */
++ private void prepareContentInsertion()
++ {
++ while (numEndTags > 0)
++ {
++ elementStack.pop();
++ numEndTags--;
++ }
+
+- // Add new paragraph into document structure.
+- Element[] added = new Element[]{newParagraph};
+- root.replace(index + 1, 0, added);
+- ElementEdit edit = new ElementEdit(root, index + 1, new Element[0],
+- added);
+- documentEvent.addEdit(edit);
++ while (numStartTags > 0)
++ {
++ Element current = (Element) elementStack.peek();
++ Element newParagraph =
++ insertParagraph((BranchElement) current, offset);
++ elementStack.push(newParagraph);
++ numStartTags--;
++ }
++ }
+
+- // Maybe add fractured elements.
+- if (tag.getDirection() == ElementSpec.JoinFractureDirection)
++ private Element insertParagraph(BranchElement par, int offset)
++ {
++ Element current = par.getElement(par.getElementIndex(offset));
++ Element[] res = split(current, offset, 0);
++ int index = par.getElementIndex(offset);
++ Element ret;
++ if (res[1] != null)
+ {
+- Element[] newFracture = new Element[fracture.length];
+- for (int i = 0; i < fracture.length; i++)
++ Element[] removed;
++ Element[] added;
++ if (res[0] == null)
+ {
+- Element oldLeaf = fracture[i];
+- Element newLeaf = createLeafElement(newParagraph,
+- oldLeaf.getAttributes(),
+- oldLeaf.getStartOffset(),
+- oldLeaf.getEndOffset());
+- newFracture[i] = newLeaf;
++ removed = new Element[0];
++ if (res[1] instanceof BranchElement)
++ {
++ added = new Element[]{ res[1] };
++ ret = res[1];
++ }
++ else
++ {
++ ret = createBranchElement(par, null);
++ added = new Element[]{ ret, res[1] };
++ }
++ index++;
+ }
+- newParagraph.replace(0, 0, newFracture);
+- edit = new ElementEdit(newParagraph, 0, new Element[0],
+- fracture);
+- documentEvent.addEdit(edit);
+- fracture = new Element[0];
++ else
++ {
++ removed = new Element[]{ current };
++ if (res[1] instanceof BranchElement)
++ {
++ ret = res[1];
++ added = new Element[]{ res[0], res[1] };
++ }
++ else
++ {
++ ret = createBranchElement(par, null);
++ added = new Element[]{ res[0], ret, res[1] };
++ }
++ }
++ par.replace(index, removed.length, added);
++ addEdit(par, index, removed, added);
+ }
++ else
++ {
++ ret = createBranchElement(par, null);
++ Element[] added = new Element[]{ ret };
++ par.replace(index, 0, added);
++ addEdit(par, index, new Element[0], added);
++ }
++ return ret;
+ }
+-
++
+ /**
+- * Inserts an end tag into the document structure. This cuts of the
+- * current paragraph element, possibly fracturing it's child elements.
+- * The fractured elements are saved so that they can be joined later
+- * with a new paragraph element.
++ * Inserts a fracture into the document structure.
++ *
++ * @param tag - the element spec.
+ */
+- void insertEndTag(ElementSpec tag)
++ private void insertFracture(ElementSpec tag)
+ {
+- BranchElement root = (BranchElement) getDefaultRootElement();
+- int parIndex = root.getElementIndex(offset);
+- BranchElement paragraph = (BranchElement) root.getElement(parIndex);
+-
+- int index = paragraph.getElementIndex(offset);
+- LeafElement content = (LeafElement) paragraph.getElement(index);
+- // We might have to split the element at offset.
+- split(content, offset);
+- index = paragraph.getElementIndex(offset);
+-
+- int count = paragraph.getElementCount();
+- // Store fractured elements.
+- fracture = new Element[count - index];
+- for (int i = index; i < count; ++i)
+- fracture[i - index] = paragraph.getElement(i);
+-
+- // Delete fractured elements.
+- paragraph.replace(index, count - index, new Element[0]);
+-
+- // Add this action to the document event.
+- ElementEdit edit = new ElementEdit(paragraph, index, fracture,
+- new Element[0]);
+- documentEvent.addEdit(edit);
++ // This is the parent of the paragraph about to be fractured. We will
++ // create a new child of this parent.
++ BranchElement parent = (BranchElement) elementStack.peek();
++ int parentIndex = parent.getElementIndex(offset);
++
++ // This is the old paragraph. We must remove all its children that
++ // occur after offset and move them to a new paragraph. We must
++ // also recreate its child that occurs at offset to have the proper
++ // end offset. The remainder of this child will also go in the new
++ // paragraph.
++ BranchElement previous = (BranchElement) parent.getElement(parentIndex);
++
++ // This is the new paragraph.
++ BranchElement newBranch =
++ (BranchElement) createBranchElement(parent, previous.getAttributes());
++
++
++ // The steps we must take to properly fracture are:
++ // 1. Recreate the LeafElement at offset to have the correct end offset.
++ // 2. Create a new LeafElement with the remainder of the LeafElement in
++ // #1 ==> this is whatever was in that LeafElement to the right of the
++ // inserted newline.
++ // 3. Find the paragraph at offset and remove all its children that
++ // occur _after_ offset. These will be moved to the newly created
++ // paragraph.
++ // 4. Move the LeafElement created in #2 and all the LeafElements removed
++ // in #3 to the newly created paragraph.
++ // 5. Add the new paragraph to the parent.
++ int previousIndex = previous.getElementIndex(offset);
++ int numReplaced = previous.getElementCount() - previousIndex;
++ Element previousLeaf = previous.getElement(previousIndex);
++ AttributeSet prevLeafAtts = previous.getAttributes();
++
++ // This recreates the child at offset to have the proper end offset.
++ // (Step 1).
++ Element newPreviousLeaf =
++ createLeafElement(previous,
++ prevLeafAtts, previousLeaf.getStartOffset(),
++ offset);
++ // This creates the new child, which is the remainder of the old child.
++ // (Step 2).
++
++ Element firstLeafInNewBranch =
++ createLeafElement(newBranch, prevLeafAtts,
++ offset, previousLeaf.getEndOffset());
++
++ // Now we move the new LeafElement and all the old children that occurred
++ // after the offset to the new paragraph. (Step 4).
++ Element[] newLeaves = new Element[numReplaced];
++ newLeaves[0] = firstLeafInNewBranch;
++ for (int i = 1; i < numReplaced; i++)
++ newLeaves[i] = previous.getElement(previousIndex + i);
++ newBranch.replace(0, 0, newLeaves);
++ addEdit(newBranch, 0, null, newLeaves);
++
++ // Now we remove the children after the offset from the previous
++ // paragraph. (Step 3).
++ int removeSize = previous.getElementCount() - previousIndex;
++ Element[] add = new Element[] { newPreviousLeaf };
++ Element[] remove = new Element[removeSize];
++ for (int j = 0; j < removeSize; j++)
++ remove[j] = previous.getElement(previousIndex + j);
++ previous.replace(previousIndex, removeSize, add);
++ addEdit(previous, previousIndex, remove, add);
++
++ // Finally we add the new paragraph to the parent. (Step 5).
++ Element[] nb = new Element[] { newBranch };
++ int index = parentIndex + 1;
++ parent.replace(index, 0, nb);
++ addEdit(parent, index, null, nb);
+ }
+-
++
+ /**
+ * Inserts a content element into the document structure.
+- *
++ *
+ * @param tag the element spec
+ */
+- void insertContentTag(ElementSpec tag)
++ private void insertContentTag(ElementSpec tag)
+ {
++ prepareContentInsertion();
+ int len = tag.getLength();
+ int dir = tag.getDirection();
++ AttributeSet tagAtts = tag.getAttributes();
+ if (dir == ElementSpec.JoinPreviousDirection)
+ {
+- Element prev = getCharacterElement(offset);
+- BranchElement prevParent = (BranchElement) prev.getParentElement();
+- Element join = createLeafElement(prevParent, tag.getAttributes(),
+- prev.getStartOffset(),
+- Math.max(prev.getEndOffset(),
+- offset + len));
+- int ind = prevParent.getElementIndex(offset);
+- if (ind == -1)
+- ind = 0;
+- Element[] add = new Element[]{join};
+- prevParent.replace(ind, 1, add);
+-
+- // Add this action to the document event.
+- ElementEdit edit = new ElementEdit(prevParent, ind,
+- new Element[]{prev}, add);
+- documentEvent.addEdit(edit);
++ // The mauve tests to this class show that a JoinPrevious insertion
++ // does not add any edits to the document event. To me this means
++ // that nothing is done here. The previous element naturally should
++ // expand so that it covers the new characters.
+ }
+ else if (dir == ElementSpec.JoinNextDirection)
+ {
+- Element next = getCharacterElement(offset + len);
+- BranchElement nextParent = (BranchElement) next.getParentElement();
+- Element join = createLeafElement(nextParent, tag.getAttributes(),
+- offset,
+- next.getEndOffset());
+- int ind = nextParent.getElementIndex(offset + len);
+- if (ind == -1)
+- ind = 0;
+- Element[] add = new Element[]{join};
+- nextParent.replace(ind, 1, add);
+-
+- // Add this action to the document event.
+- ElementEdit edit = new ElementEdit(nextParent, ind,
+- new Element[]{next}, add);
+- documentEvent.addEdit(edit);
++ // FIXME:
++ // Have to handle JoinNext differently depending on whether
++ // or not it comes after a fracture. If comes after a fracture,
++ // the insertFracture method takes care of everything and nothing
++ // needs to be done here. Otherwise, we need to adjust the
++ // Element structure. For now, I check if the elementStack's
++ // top Element is the immediate parent of the LeafElement at
++ // offset - if so, we did not come immediately after a
++ // fracture. This seems awkward and should probably be improved.
++ // We may be doing too much in insertFracture because we are
++ // adjusting the offsets, the correct thing to do may be to
++ // create a new branch element and push it on to element stack
++ // and then this method here can be more general.
++
++ BranchElement paragraph = (BranchElement) elementStack.peek();
++ int index = paragraph.getElementIndex(offset);
++ Element target = paragraph.getElement(index);
++ if (target.isLeaf() && paragraph.getElementCount() > (index + 1))
++ {
++ Element next = paragraph.getElement(index + 1);
++ Element newEl1 = createLeafElement(paragraph,
++ target.getAttributes(),
++ target.getStartOffset(),
++ offset);
++ Element newEl2 = createLeafElement(paragraph,
++ next.getAttributes(), offset,
++ next.getEndOffset());
++ Element[] add = new Element[] { newEl1, newEl2 };
++ paragraph.replace (index, 2, add);
++ addEdit(paragraph, index, new Element[] { target, next }, add);
++ }
+ }
+- else
++ else if (dir == ElementSpec.OriginateDirection)
+ {
+- BranchElement par = (BranchElement) getParagraphElement(offset);
+-
+- int ind = par.getElementIndex(offset);
+-
+- // Make room for the element.
+- // Cut previous element.
+- Element prev = par.getElement(ind);
+- if (prev != null && prev.getStartOffset() < offset)
++ BranchElement paragraph = (BranchElement) elementStack.peek();
++ int index = paragraph.getElementIndex(offset);
++ Element current = paragraph.getElement(index);
++
++ Element[] added;
++ Element[] removed = new Element[] {current};
++ Element[] splitRes = split(current, offset, length);
++ if (splitRes[0] == null)
+ {
+- Element cutPrev = createLeafElement(par, prev.getAttributes(),
+- prev.getStartOffset(),
+- offset);
+- Element[] remove = new Element[]{prev};
+- Element[] add = new Element[]{cutPrev};
+- if (prev.getEndOffset() > offset + len)
+- {
+- Element rem = createLeafElement(par, prev.getAttributes(),
+- offset + len,
+- prev.getEndOffset());
+- add = new Element[]{cutPrev, rem};
+- }
+-
+- par.replace(ind, 1, add);
+- documentEvent.addEdit(new ElementEdit(par, ind, remove, add));
+- ind++;
++ added = new Element[2];
++ added[0] = createLeafElement(paragraph, tagAtts,
++ offset, endOffset);
++ added[1] = splitRes[1];
++ removed = new Element[0];
++ index++;
+ }
+- // ind now points to the next element.
+-
+- // Cut next element if necessary.
+- Element next = par.getElement(ind);
+- if (next != null && next.getStartOffset() < offset + len)
++ else if (current.getStartOffset() == offset)
++ {
++ // This is if the new insertion happens immediately before
++ // the current
Element. In this case there are 2
++ // resulting Elements.
++ added = new Element[2];
++ added[0] = createLeafElement(paragraph, tagAtts, offset,
++ endOffset);
++ added[1] = splitRes[1];
++ }
++ else if (current.getEndOffset() == endOffset)
+ {
+- Element cutNext = createLeafElement(par, next.getAttributes(),
+- offset + len,
+- next.getEndOffset());
+- Element[] remove = new Element[]{next};
+- Element[] add = new Element[]{cutNext};
+- par.replace(ind, 1, add);
+- documentEvent.addEdit(new ElementEdit(par, ind, remove,
+- add));
++ // This is if the new insertion happens right at the end of
++ // the current
Element. In this case there are
++ // 2 resulting Elements.
++ added = new Element[2];
++ added[0] = splitRes[0];
++ added[1] = createLeafElement(paragraph, tagAtts, offset,
++ endOffset);
+ }
+-
+- // Insert new element.
+- Element newEl = createLeafElement(par, tag.getAttributes(),
+- offset, offset + len);
+- Element[] added = new Element[]{newEl};
+- par.replace(ind, 0, added);
+- // Add this action to the document event.
+- ElementEdit edit = new ElementEdit(par, ind, new Element[0],
+- added);
+- documentEvent.addEdit(edit);
++ else
++ {
++ // This is if the new insertion is in the middle of the
++ // current
Element. In this case
++ // there will be 3 resulting Elements.
++ added = new Element[3];
++ added[0] = splitRes[0];
++ added[1] = createLeafElement(paragraph, tagAtts, offset,
++ endOffset);
++ added[2] = splitRes[1];
++ }
++ paragraph.replace(index, removed.length, added);
++ addEdit(paragraph, index, removed, added);
+ }
+ offset += len;
+ }
+@@ -800,6 +1152,79 @@
+ result.replace(0, 0, children);
+ return result;
+ }
++
++ /**
++ * Adds an ElementChange for a given element modification to the document
++ * event. If there already is an ElementChange registered for this element,
++ * this method tries to merge the ElementChanges together. However, this
++ * is only possible if the indices of the new and old ElementChange are
++ * equal.
++ *
++ * @param e the element
++ * @param i the index of the change
++ * @param removed the removed elements, or null
++ * @param added the added elements, or null
++ */
++ private void addEdit(Element e, int i, Element[] removed, Element[] added)
++ {
++ // Perform sanity check first.
++ DocumentEvent.ElementChange ec = documentEvent.getChange(e);
++
++ // Merge the existing stuff with the new stuff.
++ Element[] oldAdded = ec == null ? null: ec.getChildrenAdded();
++ Element[] newAdded;
++ if (oldAdded != null && added != null)
++ {
++ if (ec.getIndex() <= i)
++ {
++ int index = i - ec.getIndex();
++ // Merge adds together.
++ newAdded = new Element[oldAdded.length + added.length];
++ System.arraycopy(oldAdded, 0, newAdded, 0, index);
++ System.arraycopy(added, 0, newAdded, index, added.length);
++ System.arraycopy(oldAdded, index, newAdded, index + added.length,
++ oldAdded.length - index);
++ i = ec.getIndex();
++ }
++ else
++ throw new AssertionError("Not yet implemented case.");
++ }
++ else if (added != null)
++ newAdded = added;
++ else if (oldAdded != null)
++ newAdded = oldAdded;
++ else
++ newAdded = new Element[0];
++
++ Element[] oldRemoved = ec == null ? null: ec.getChildrenRemoved();
++ Element[] newRemoved;
++ if (oldRemoved != null && removed != null)
++ {
++ if (ec.getIndex() <= i)
++ {
++ int index = i - ec.getIndex();
++ // Merge removes together.
++ newRemoved = new Element[oldRemoved.length + removed.length];
++ System.arraycopy(oldAdded, 0, newRemoved, 0, index);
++ System.arraycopy(removed, 0, newRemoved, index, removed.length);
++ System.arraycopy(oldRemoved, index, newRemoved,
++ index + removed.length,
++ oldRemoved.length - index);
++ i = ec.getIndex();
++ }
++ else
++ throw new AssertionError("Not yet implemented case.");
++ }
++ else if (removed != null)
++ newRemoved = removed;
++ else if (oldRemoved != null)
++ newRemoved = oldRemoved;
++ else
++ newRemoved = new Element[0];
++
++ // Replace the existing edit for the element with the merged.
++ documentEvent.addEdit(new ElementEdit(e, i, newRemoved, newAdded));
++ }
+ }
+
+ /**
+@@ -824,7 +1249,7 @@
+ */
+ public String getName()
+ {
+- return "section";
++ return SectionElementName;
+ }
+ }
+
+@@ -945,9 +1370,7 @@
+ // Use createBranchElement() and createLeafElement instead.
+ SectionElement section = new SectionElement();
+
+- BranchElement paragraph =
+- (BranchElement) createBranchElement(section, null);
+- paragraph.setResolveParent(getStyle(StyleContext.DEFAULT_STYLE));
++ BranchElement paragraph = new BranchElement(section, null);
+ tmp = new Element[1];
+ tmp[0] = paragraph;
+ section.replace(0, 0, tmp);
+@@ -1043,7 +1466,11 @@
+ {
+ Element paragraph = getParagraphElement(position);
+ AttributeSet attributes = paragraph.getAttributes();
+- return (Style) attributes.getResolveParent();
++ AttributeSet a = attributes.getResolveParent();
++ // If the resolve parent is not of type Style, we return null.
++ if (a instanceof Style)
++ return (Style) a;
++ return null;
+ }
+
+ /**
+@@ -1112,50 +1539,54 @@
+ AttributeSet attributes,
+ boolean replace)
+ {
+- DefaultDocumentEvent ev =
+- new DefaultDocumentEvent(offset, length,
+- DocumentEvent.EventType.CHANGE);
++ // Exit early if length is 0, so no DocumentEvent is created or fired.
++ if (length == 0)
++ return;
++ try
++ {
++ // Must obtain a write lock for this method. writeLock() and
++ // writeUnlock() should always be in try/finally block to make
++ // sure that locking happens in a balanced manner.
++ writeLock();
++ DefaultDocumentEvent ev =
++ new DefaultDocumentEvent(
++ offset,
++ length,
++ DocumentEvent.EventType.CHANGE);
+
+- // Modify the element structure so that the interval begins at an element
+- // start and ends at an element end.
+- buffer.change(offset, length, ev);
++ // Modify the element structure so that the interval begins at an
++ // element
++ // start and ends at an element end.
++ buffer.change(offset, length, ev);
+
+- Element root = getDefaultRootElement();
+- // Visit all paragraph elements within the specified interval
+- int paragraphCount = root.getElementCount();
+- for (int pindex = 0; pindex < paragraphCount; pindex++)
+- {
+- Element paragraph = root.getElement(pindex);
+- // Skip paragraphs that lie outside the interval.
+- if ((paragraph.getStartOffset() > offset + length)
+- || (paragraph.getEndOffset() < offset))
+- continue;
+-
+- // Visit content elements within this paragraph
+- int contentCount = paragraph.getElementCount();
+- for (int cindex = 0; cindex < contentCount; cindex++)
++ Element root = getDefaultRootElement();
++ // Visit all paragraph elements within the specified interval
++ int end = offset + length;
++ Element curr;
++ for (int pos = offset; pos < end; )
+ {
+- Element content = paragraph.getElement(cindex);
+- // Skip content that lies outside the interval.
+- if ((content.getStartOffset() > offset + length)
+- || (content.getEndOffset() < offset))
+- continue;
+-
+- if (content instanceof AbstractElement)
+- {
+- AbstractElement el = (AbstractElement) content;
+- if (replace)
+- el.removeAttributes(el);
+- el.addAttributes(attributes);
+- }
+- else
+- throw new AssertionError("content elements are expected to be"
+- + "instances of "
+- + "javax.swing.text.AbstractDocument.AbstractElement");
++ // Get the CharacterElement at offset pos.
++ curr = getCharacterElement(pos);
++ if (pos == curr.getEndOffset())
++ break;
++
++ MutableAttributeSet a = (MutableAttributeSet) curr.getAttributes();
++ ev.addEdit(new AttributeUndoableEdit(curr, attributes, replace));
++ // If replace is true, remove all the old attributes.
++ if (replace)
++ a.removeAttributes(a);
++ // Add all the new attributes.
++ a.addAttributes(attributes);
++ // Increment pos so we can check the next CharacterElement.
++ pos = curr.getEndOffset();
+ }
++ fireChangedUpdate(ev);
++ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
+-
+- fireChangedUpdate(ev);
++ finally
++ {
++ writeUnlock();
++ }
+ }
+
+ /**
+@@ -1167,14 +1598,36 @@
+ public void setLogicalStyle(int position, Style style)
+ {
+ Element el = getParagraphElement(position);
+- if (el instanceof AbstractElement)
+- {
+- AbstractElement ael = (AbstractElement) el;
+- ael.setResolveParent(style);
+- }
+- else
+- throw new AssertionError("paragraph elements are expected to be"
+- + "instances of javax.swing.text.AbstractDocument.AbstractElement");
++ // getParagraphElement doesn't return null but subclasses might so
++ // we check for null here.
++ if (el == null)
++ return;
++ try
++ {
++ writeLock();
++ if (el instanceof AbstractElement)
++ {
++ AbstractElement ael = (AbstractElement) el;
++ ael.setResolveParent(style);
++ int start = el.getStartOffset();
++ int end = el.getEndOffset();
++ DefaultDocumentEvent ev =
++ new DefaultDocumentEvent (
++ start,
++ end - start,
++ DocumentEvent.EventType.CHANGE);
++ // FIXME: Add an UndoableEdit to this event and fire it.
++ fireChangedUpdate(ev);
++ }
++ else
++ throw new
++ AssertionError("paragraph elements are expected to be"
++ + "instances of AbstractDocument.AbstractElement");
++ }
++ finally
++ {
++ writeUnlock();
++ }
+ }
+
+ /**
+@@ -1190,16 +1643,48 @@
+ AttributeSet attributes,
+ boolean replace)
+ {
+- int index = offset;
+- while (index < offset + length)
++ try
+ {
+- AbstractElement par = (AbstractElement) getParagraphElement(index);
+- AttributeContext ctx = getAttributeContext();
+- if (replace)
+- par.removeAttributes(par);
+- par.addAttributes(attributes);
+- index = par.getElementCount();
++ // Must obtain a write lock for this method. writeLock() and
++ // writeUnlock() should always be in try/finally blocks to make
++ // sure that locking occurs in a balanced manner.
++ writeLock();
++
++ // Create a DocumentEvent to use for changedUpdate().
++ DefaultDocumentEvent ev =
++ new DefaultDocumentEvent (
++ offset,
++ length,
++ DocumentEvent.EventType.CHANGE);
++
++ // Have to iterate through all the _paragraph_ elements that are
++ // contained or partially contained in the interval
++ // (offset, offset + length).
++ Element rootElement = getDefaultRootElement();
++ int startElement = rootElement.getElementIndex(offset);
++ int endElement = rootElement.getElementIndex(offset + length - 1);
++ if (endElement < startElement)
++ endElement = startElement;
++
++ for (int i = startElement; i <= endElement; i++)
++ {
++ Element par = rootElement.getElement(i);
++ MutableAttributeSet a = (MutableAttributeSet) par.getAttributes();
++ // Add the change to the DocumentEvent.
++ ev.addEdit(new AttributeUndoableEdit(par, attributes, replace));
++ // If replace is true remove the old attributes.
++ if (replace)
++ a.removeAttributes(a);
++ // Add the new attributes.
++ a.addAttributes(attributes);
++ }
++ fireChangedUpdate(ev);
++ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
++ finally
++ {
++ writeUnlock();
++ }
+ }
+
+ /**
+@@ -1212,9 +1697,14 @@
+ protected void insertUpdate(DefaultDocumentEvent ev, AttributeSet attr)
+ {
+ super.insertUpdate(ev, attr);
++ // If the attribute set is null, use an empty attribute set.
++ if (attr == null)
++ attr = SimpleAttributeSet.EMPTY;
+ int offset = ev.getOffset();
+ int length = ev.getLength();
+ int endOffset = offset + length;
++ AttributeSet paragraphAttributes =
++ getParagraphElement(endOffset).getAttributes();
+ Segment txt = new Segment();
+ try
+ {
+@@ -1229,66 +1719,141 @@
+
+ int len = 0;
+ Vector specs = new Vector();
+-
++ ElementSpec finalStartTag = null;
++ short finalStartDirection = ElementSpec.OriginateDirection;
++ boolean prevCharWasNewline = false;
+ Element prev = getCharacterElement(offset);
+- Element next = getCharacterElement(endOffset);
++ Element next = getCharacterElement(endOffset);
++ Element prevParagraph = getParagraphElement(offset);
++ Element paragraph = getParagraphElement(endOffset);
++
++ int segmentEnd = txt.offset + txt.count;
++
++ // Check to see if we're inserting immediately after a newline.
++ if (offset > 0)
++ {
++ try
++ {
++ String s = getText(offset - 1, 1);
++ if (s.equals("\n"))
++ {
++ finalStartDirection =
++ handleInsertAfterNewline(specs, offset, endOffset,
++ prevParagraph,
++ paragraph,
++ paragraphAttributes);
++
++ prevCharWasNewline = true;
++ // Find the final start tag from the ones just created.
++ for (int i = 0; i < specs.size(); i++)
++ if (((ElementSpec) specs.get(i)).getType()
++ == ElementSpec.StartTagType)
++ finalStartTag = (ElementSpec)specs.get(i);
++ }
++ }
++ catch (BadLocationException ble)
++ {
++ // This shouldn't happen.
++ AssertionError ae = new AssertionError();
++ ae.initCause(ble);
++ throw ae;
++ }
++ }
+
+- for (int i = offset; i < endOffset; ++i)
++
++ for (int i = txt.offset; i < segmentEnd; ++i)
+ {
+ len++;
+ if (txt.array[i] == '\n')
+ {
+- ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType,
+- len);
++ // Add the ElementSpec for the content.
++ specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
+
+- // If we are at the last index, then check if we could probably be
+- // joined with the next element.
+- if (i == endOffset - 1)
+- {
+- if (next.getAttributes().isEqual(attr))
+- spec.setDirection(ElementSpec.JoinNextDirection);
+- }
+- // If we are at the first new element, then check if it could be
+- // joined with the previous element.
+- else if (specs.size() == 0)
+- {
+- if (prev.getAttributes().isEqual(attr))
+- spec.setDirection(ElementSpec.JoinPreviousDirection);
+- }
+-
+- specs.add(spec);
+-
+ // Add ElementSpecs for the newline.
+- ElementSpec endTag = new ElementSpec(null, ElementSpec.EndTagType);
+- specs.add(endTag);
+- ElementSpec startTag = new ElementSpec(null,
++ specs.add(new ElementSpec(null, ElementSpec.EndTagType));
++ finalStartTag = new ElementSpec(paragraphAttributes,
+ ElementSpec.StartTagType);
+- startTag.setDirection(ElementSpec.JoinFractureDirection);
+- specs.add(startTag);
+-
++ specs.add(finalStartTag);
+ len = 0;
+- offset += len;
+ }
+ }
+
+ // Create last element if last character hasn't been a newline.
+- if (len > 0)
++ if (len > 0)
++ specs.add(new ElementSpec(attr, ElementSpec.ContentType, len));
++
++ // Set the direction of the last spec of type StartTagType.
++ // If we are inserting after a newline then this value comes from
++ // handleInsertAfterNewline.
++ if (finalStartTag != null)
++ {
++ if (prevCharWasNewline)
++ finalStartTag.setDirection(finalStartDirection);
++ else if (prevParagraph.getEndOffset() != endOffset)
++ {
++ try
++ {
++ String last = getText(endOffset - 1, 1);
++ if (!last.equals("\n"))
++ finalStartTag.setDirection(ElementSpec.JoinFractureDirection);
++ }
++ catch (BadLocationException ble)
++ {
++ // This shouldn't happen.
++ AssertionError ae = new AssertionError();
++ ae.initCause(ble);
++ throw ae;
++ }
++ }
++ else
++ {
++ // If there is an element AFTER this one, then set the
++ // direction to JoinNextDirection.
++ Element parent = prevParagraph.getParentElement();
++ int index = parent.getElementIndex(offset);
++ if (index + 1 < parent.getElementCount()
++ && !parent.getElement(index + 1).isLeaf())
++ finalStartTag.setDirection(ElementSpec.JoinNextDirection);
++ }
++ }
++
++ // If we are at the last index, then check if we could probably be
++ // joined with the next element.
++ // This means:
++ // - we must be a ContentTag
++ // - if there is a next Element, we must have the same attributes
++ // - if there is no next Element, but one will be created,
++ // we must have the same attributes as the higher-level run.
++ ElementSpec last = (ElementSpec) specs.lastElement();
++ if (last.getType() == ElementSpec.ContentType)
+ {
+- ElementSpec spec = new ElementSpec(attr, ElementSpec.ContentType, len);
+- // If we are at the first new element, then check if it could be
+- // joined with the previous element.
+- if (specs.size() == 0)
++ Element currentRun =
++ prevParagraph.getElement(prevParagraph.getElementIndex(offset));
++ if (currentRun.getEndOffset() == endOffset)
+ {
+- if (prev.getAttributes().isEqual(attr))
+- spec.setDirection(ElementSpec.JoinPreviousDirection);
++ if (endOffset < getLength() && next.getAttributes().isEqual(attr)
++ && last.getType() == ElementSpec.ContentType)
++ last.setDirection(ElementSpec.JoinNextDirection);
+ }
+- // Check if we could probably be joined with the next element.
+- else if (next.getAttributes().isEqual(attr))
+- spec.setDirection(ElementSpec.JoinNextDirection);
+-
+- specs.add(spec);
++ else
++ {
++ if (finalStartTag != null
++ && finalStartTag.getDirection() ==
++ ElementSpec.JoinFractureDirection
++ && currentRun.getAttributes().isEqual(attr))
++ {
++ last.setDirection(ElementSpec.JoinNextDirection);
++ }
++ }
+ }
+-
++
++ // If we are at the first new element, then check if it could be
++ // joined with the previous element.
++ ElementSpec first = (ElementSpec) specs.firstElement();
++ if (prev.getAttributes().isEqual(attr)
++ && first.getType() == ElementSpec.ContentType)
++ first.setDirection(ElementSpec.JoinPreviousDirection);
++
+ ElementSpec[] elSpecs =
+ (ElementSpec[]) specs.toArray(new ElementSpec[specs.size()]);
+
+@@ -1296,6 +1861,47 @@
+ }
+
+ /**
++ * A helper method to set up the ElementSpec buffer for the special
++ * case of an insertion occurring immediately after a newline.
++ * @param specs the ElementSpec buffer to initialize.
++ */
++ short handleInsertAfterNewline(Vector specs, int offset, int endOffset,
++ Element prevParagraph, Element paragraph,
++ AttributeSet a)
++ {
++ if (prevParagraph.getParentElement() == paragraph.getParentElement())
++ {
++ specs.add(new ElementSpec(a, ElementSpec.EndTagType));
++ specs.add(new ElementSpec(a, ElementSpec.StartTagType));
++ if (prevParagraph.getEndOffset() != endOffset)
++ return ElementSpec.JoinFractureDirection;
++ // If there is an Element after this one, use JoinNextDirection.
++ Element parent = paragraph.getParentElement();
++ if (parent.getElementCount() > parent.getElementIndex(offset) + 1)
++ return ElementSpec.JoinNextDirection;
++ }
++ else
++ {
++ // TODO: What to do here?
++ }
++ return ElementSpec.OriginateDirection;
++ }
++
++ /**
++ * Updates the document structure in response to text removal. This is
++ * forwarded to the {@link ElementBuffer} of this document. Any changes to
++ * the document structure are added to the specified document event and
++ * sent to registered listeners.
++ *
++ * @param ev the document event that records the changes to the document
++ */
++ protected void removeUpdate(DefaultDocumentEvent ev)
++ {
++ super.removeUpdate(ev);
++ buffer.remove(ev.getOffset(), ev.getLength(), ev);
++ }
++
++ /**
+ * Returns an enumeration of all style names.
+ *
+ * @return an enumeration of all style names
+@@ -1316,6 +1922,35 @@
+ // Nothing to do here. This is intended to be overridden by subclasses.
+ }
+
++ void printElements (Element start, int pad)
++ {
++ for (int i = 0; i < pad; i++)
++ System.out.print(" ");
++ if (pad == 0)
++ System.out.println ("ROOT ELEMENT ("+start.getStartOffset()+", "+start.getEndOffset()+")");
++ else if (start instanceof AbstractDocument.BranchElement)
++ System.out.println ("BranchElement ("+start.getStartOffset()+", "+start.getEndOffset()+")");
++ else
++ {
++ {
++ try
++ {
++ System.out.println ("LeafElement ("+start.getStartOffset()+", "
++ + start.getEndOffset()+"): "+
++ start.getDocument().
++ getText(start.getStartOffset(),
++ start.getEndOffset() -
++ start.getStartOffset()));
++ }
++ catch (BadLocationException ble)
++ {
++ }
++ }
++ }
++ for (int i = 0; i < start.getElementCount(); i ++)
++ printElements (start.getElement(i), pad+3);
++ }
++
+ /**
+ * Inserts a bulk of structured content at once.
+ *
+@@ -1325,36 +1960,53 @@
+ protected void insert(int offset, ElementSpec[] data)
+ throws BadLocationException
+ {
+- writeLock();
+- // First we insert the content.
+- int index = offset;
+- for (int i = 0; i < data.length; i++)
++ if (data == null || data.length == 0)
++ return;
++ try
+ {
+- ElementSpec spec = data[i];
+- if (spec.getArray() != null && spec.getLength() > 0)
++ // writeLock() and writeUnlock() should always be in a try/finally
++ // block so that locking balance is guaranteed even if some
++ // exception is thrown.
++ writeLock();
++
++ // First we collect the content to be inserted.
++ StringBuffer contentBuffer = new StringBuffer();
++ for (int i = 0; i < data.length; i++)
+ {
+- String insertString = new String(spec.getArray(), spec.getOffset(),
+- spec.getLength());
+- content.insertString(index, insertString);
++ // Collect all inserts into one so we can get the correct
++ // ElementEdit
++ ElementSpec spec = data[i];
++ if (spec.getArray() != null && spec.getLength() > 0)
++ contentBuffer.append(spec.getArray(), spec.getOffset(),
++ spec.getLength());
+ }
+- index += spec.getLength();
++
++ int length = contentBuffer.length();
++
++ // If there was no content inserted then exit early.
++ if (length == 0)
++ return;
++
++ UndoableEdit edit = content.insertString(offset,
++ contentBuffer.toString());
++
++ // Create the DocumentEvent with the ElementEdit added
++ DefaultDocumentEvent ev =
++ new DefaultDocumentEvent(offset,
++ length,
++ DocumentEvent.EventType.INSERT);
++ ev.addEdit(edit);
++
++ // Finally we must update the document structure and fire the insert
++ // update event.
++ buffer.insert(offset, length, data, ev);
++ fireInsertUpdate(ev);
++ fireUndoableEditUpdate(new UndoableEditEvent(this, ev));
+ }
+- // Update the view structure.
+- DefaultDocumentEvent ev = new DefaultDocumentEvent(offset, index - offset,
+- DocumentEvent.EventType.INSERT);
+- for (int i = 0; i < data.length; i++)
++ finally
+ {
+- ElementSpec spec = data[i];
+- AttributeSet atts = spec.getAttributes();
+- if (atts != null)
+- insertUpdate(ev, atts);
++ writeUnlock();
+ }
+-
+- // Finally we must update the document structure and fire the insert update
+- // event.
+- buffer.insert(offset, index - offset, data, ev);
+- fireInsertUpdate(ev);
+- writeUnlock();
+ }
+
+ /**
+@@ -1382,4 +2034,9 @@
+ throw err;
+ }
+ }
++
++ static boolean attributeSetsAreSame (AttributeSet a, AttributeSet b)
++ {
++ return (a == null && b == null) || (a != null && a.isEqual(b));
++ }
+ }
+Index: libjava/classpath/javax/swing/text/NumberFormatter.java
+===================================================================
+--- libjava/classpath/javax/swing/text/NumberFormatter.java (revision 0)
++++ libjava/classpath/javax/swing/text/NumberFormatter.java (revision 0)
+@@ -0,0 +1,86 @@
++/* NumberFormatter.java --
++ Copyright (C) 2005 Free Software Foundation, Inc.
++
++This file is part of GNU Classpath.
++
++GNU Classpath is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU Classpath is distributed in the hope that it will be useful, but
++WITHOUT 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 GNU Classpath; see the file COPYING. If not, write to the
++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++02110-1301 USA.
++
++Linking this library statically or dynamically with other modules is
++making a combined work based on this library. Thus, the terms and
++conditions of the GNU General Public License cover the whole
++combination.
++
++As a special exception, the copyright holders of this library give you
++permission to link this library with independent modules to produce an
++executable, regardless of the license terms of these independent
++modules, and to copy and distribute the resulting executable under
++terms of your choice, provided that you also meet, for each linked
++independent module, the terms and conditions of the license of that
++module. An independent module is a module which is not derived from
++or based on this library. If you modify this library, you may extend
++this exception to your version of the library, but you are not
++obligated to do so. If you do not wish to do so, delete this
++exception statement from your version. */
++
++
++package javax.swing.text;
++
++import java.text.Format;
++import java.text.NumberFormat;
++
++/**
++ * NumberFormatter
is an {@link InternationalFormatter}
++ * that implements value to string and string to value conversion via
++ * an instance of {@link NumberFormat}.
++ *
++ * @author Anthony Balkissoon abalkiss at redhat dot com
++ * @since 1.4
++ */
++public class NumberFormatter extends InternationalFormatter
++{
++
++ /**
++ * Creates a NumberFormatter with the default NumberFormat from
++ * NumberFormat.getNumberInstance().
++ */
++ public NumberFormatter ()
++ {
++ this (NumberFormat.getNumberInstance());
++ }
++
++ /**
++ * Creates a NumberFormatter with the specified NumberFormat.
++ * @param format the NumberFormat to use for this NumberFormatter.
++ */
++ public NumberFormatter (NumberFormat format)
++ {
++ super(format);
++ setFormat(format);
++ }
++
++ /**
++ * Sets the NumberFormat that this NumberFormatter will use to determine
++ * legal values for editing and displaying.
++ *
++ * @param format the Format to use to determine legal values.
++ */
++ public void setFormat (Format format)
++ {
++ // TODO: This should be different from the super implementation
++ // but I don't yet know how.
++ super.setFormat(format);
++ }
++}
+Index: libjava/classpath/javax/swing/text/InternationalFormatter.java
+===================================================================
+--- libjava/classpath/javax/swing/text/InternationalFormatter.java (revision 111438)
++++ libjava/classpath/javax/swing/text/InternationalFormatter.java (working copy)
+@@ -78,6 +78,8 @@
+ minimum = null;
+ maximum = null;
+ format = null;
++ setCommitsOnValidEdit(false);
++ setOverwriteMode(false);
+ }
+
+ /**
+@@ -226,6 +228,8 @@
+ public String valueToString(Object value)
+ throws ParseException
+ {
++ if (value == null)
++ return "";
+ if (format != null)
+ return format.format(value);
+ else
+Index: libjava/classpath/javax/swing/text/PasswordView.java
+===================================================================
+--- libjava/classpath/javax/swing/text/PasswordView.java (revision 111438)
++++ libjava/classpath/javax/swing/text/PasswordView.java (working copy)
+@@ -41,6 +41,7 @@
+ import java.awt.Color;
+ import java.awt.FontMetrics;
+ import java.awt.Graphics;
++import java.awt.Rectangle;
+ import java.awt.Shape;
+
+ import javax.swing.JPasswordField;
+@@ -211,7 +212,10 @@
+ /**
+ * Provides a mapping from the document model coordinate space to the
+ * coordinate space of the view mapped to it.
+- *
++ *
++ * This method is overridden to provide a correct mapping with respect to the
++ * echo char and not to the real content.
++ *
+ * @param pos - the position to convert >= 0
+ * @param a - the allocated region to render into
+ * @param b - typesafe enumeration to indicate bias to a position in the model.
+@@ -222,7 +226,35 @@
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+- return super.modelToView(pos, a, b);
++ Shape newAlloc = adjustAllocation(a);
++
++ // Ensure metrics are up-to-date.
++ updateMetrics();
++
++ // Get rectangle of the line containing position.
++ int lineIndex = getElement().getElementIndex(pos);
++ Rectangle rect = lineToRect(newAlloc, lineIndex);
++
++ // Get the rectangle for position.
++ Element line = getElement().getElement(lineIndex);
++ int lineStart = line.getStartOffset();
++ Segment segment = getLineBuffer();
++ segment.array = new char[pos - lineStart];
++ char echoChar = getEchoChar();
++ for (int i = 0; i < segment.array.length; ++i)
++ segment.array[i] = echoChar;
++ segment.offset = 0;
++ segment.count = segment.array.length;
++
++ int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
++ this, lineStart);
++
++ // Calc the real rectangle.
++ rect.x += xoffset;
++ rect.width = 1;
++ rect.height = metrics.getHeight();
++
++ return rect;
+ }
+
+ /**
+@@ -239,6 +271,8 @@
+ */
+ public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias)
+ {
++ // FIXME: This only provides a view->model mapping for the real text
++ // content and does not respect the echo char.
+ return super.viewToModel(fx, fy, a, bias);
+ }
+ }
+Index: libjava/classpath/javax/swing/text/DefaultEditorKit.java
+===================================================================
+--- libjava/classpath/javax/swing/text/DefaultEditorKit.java (revision 111438)
++++ libjava/classpath/javax/swing/text/DefaultEditorKit.java (working copy)
+@@ -38,8 +38,10 @@
+
+ package javax.swing.text;
+
++import java.awt.Point;
+ import java.awt.Toolkit;
+ import java.awt.event.ActionEvent;
++
+ import java.io.BufferedReader;
+ import java.io.IOException;
+ import java.io.InputStream;
+@@ -112,8 +114,7 @@
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+- // FIXME: Implement me. Tookit.getSystemClipboard should be used
+- // for that.
++ getTextComponent(event).copy();
+ }
+ }
+
+@@ -144,8 +145,7 @@
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+- // FIXME: Implement me. Tookit.getSystemClipboard should be used
+- // for that.
++ getTextComponent(event).cut();
+ }
+ }
+
+@@ -174,8 +174,7 @@
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+- // FIXME: Implement me. Tookit.getSystemClipboard should be used
+- // for that.
++ getTextComponent(event).paste();
+ }
+ }
+
+@@ -216,19 +215,9 @@
+ return;
+
+ JTextComponent t = getTextComponent(event);
+- if (t != null)
+- {
+- try
+- {
+- t.getDocument().insertString(t.getCaret().getDot(),
+- event.getActionCommand(), null);
+- }
+- catch (BadLocationException be)
+- {
+- // FIXME: we're not authorized to throw this.. swallow it?
+- }
+- }
+- }
++ if (t != null && t.isEnabled() && t.isEditable())
++ t.replaceSelection(event.getActionCommand());
++ }
+ }
+
+ /**
+@@ -309,7 +298,8 @@
+ */
+ public void actionPerformed(ActionEvent event)
+ {
+- // FIXME: Implement this.
++ JTextComponent t = getTextComponent(event);
++ t.replaceSelection("\t");
+ }
+ }
+
+@@ -710,6 +700,53 @@
+ new InsertContentAction(),
+ new InsertTabAction(),
+ new PasteAction(),
++ new TextAction(beginLineAction)
++ {
++ public void actionPerformed(ActionEvent event)
++ {
++ JTextComponent t = getTextComponent(event);
++ try
++ {
++ // TODO: There is a more efficent solution, but
++ // viewToModel doesn't work properly.
++ Point p = t.modelToView(t.getCaret().getDot()).getLocation();
++ int cur = t.getCaretPosition();
++ int y = p.y;
++ while (y == p.y && cur > 0)
++ y = t.modelToView(--cur).getLocation().y;
++ if (cur != 0)
++ cur++;
++ t.setCaretPosition(cur);
++ }
++ catch (BadLocationException ble)
++ {
++ // Do nothing here.
++ }
++ }
++ },
++ new TextAction(endLineAction)
++ {
++ public void actionPerformed(ActionEvent event)
++ {
++ JTextComponent t = getTextComponent(event);
++ try
++ {
++ Point p = t.modelToView(t.getCaret().getDot()).getLocation();
++ int cur = t.getCaretPosition();
++ int y = p.y;
++ int length = t.getDocument().getLength();
++ while (y == p.y && cur < length)
++ y = t.modelToView(++cur).getLocation().y;
++ if (cur != length)
++ cur--;
++ t.setCaretPosition(cur);
++ }
++ catch (BadLocationException ble)
++ {
++ // Nothing to do here
++ }
++ }
++ },
+ new TextAction(deleteNextCharAction)
+ {
+ public void actionPerformed(ActionEvent event)
+@@ -911,7 +948,7 @@
+ content.append("\n");
+ }
+
+- document.insertString(offset, content.toString(),
++ document.insertString(offset, content.substring(0, content.length() - 1),
+ SimpleAttributeSet.EMPTY);
+ }
+
+Index: libjava/classpath/javax/swing/text/DefaultCaret.java
+===================================================================
+--- libjava/classpath/javax/swing/text/DefaultCaret.java (revision 111438)
++++ libjava/classpath/javax/swing/text/DefaultCaret.java (working copy)
+@@ -1,5 +1,5 @@
+ /* DefaultCaret.java --
+- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
++ Copyright (C) 2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+@@ -430,19 +430,46 @@
+ */
+ public void focusGained(FocusEvent event)
+ {
+- setVisible(true);
++ setVisible(true);
++ updateTimerStatus();
+ }
+
+ /**
+ * Sets the caret to invisible
.
+- *
++ *
+ * @param event the FocusEvent
+ */
+ public void focusLost(FocusEvent event)
+ {
+ if (event.isTemporary() == false)
+- setVisible(false);
++ {
++ setVisible(false);
++ // Stop the blinker, if running.
++ if (blinkTimer != null && blinkTimer.isRunning())
++ blinkTimer.stop();
++ }
+ }
++
++ /**
++ * Install (if not present) and start the timer, if the caret must blink. The
++ * caret does not blink if it is invisible, or the component is disabled or
++ * not editable.
++ */
++ private void updateTimerStatus()
++ {
++ if (textComponent.isEnabled() && textComponent.isEditable())
++ {
++ if (blinkTimer == null)
++ initBlinkTimer();
++ if (!blinkTimer.isRunning())
++ blinkTimer.start();
++ }
++ else
++ {
++ if (blinkTimer != null)
++ blinkTimer.stop();
++ }
++ }
+
+ /**
+ * Moves the caret to the position specified in the MouseEvent
.
+@@ -641,8 +668,10 @@
+ }
+ catch (BadLocationException e)
+ {
+- assert false : "Unexpected bad caret location: " + dot;
+- return;
++ AssertionError ae;
++ ae = new AssertionError("Unexpected bad caret location: " + dot);
++ ae.initCause(e);
++ throw ae;
+ }
+
+ if (rect == null)
+@@ -802,9 +831,12 @@
+ public void setDot(int dot)
+ {
+ if (dot >= 0)
+- {
++ {
++ Document doc = textComponent.getDocument();
++ if (doc != null)
++ this.dot = Math.min(dot, doc.getLength());
++ this.dot = Math.max(this.dot, 0);
+ this.mark = dot;
+- this.dot = dot;
+ handleHighlight();
+ adjustVisibility(this);
+ appear();
+@@ -833,13 +865,17 @@
+ visible = true;
+
+ Rectangle area = null;
++ int dot = getDot();
+ try
+ {
+- area = getComponent().modelToView(getDot());
++ area = getComponent().modelToView(dot);
+ }
+- catch (BadLocationException ex)
++ catch (BadLocationException e)
+ {
+- assert false : "Unexpected bad caret location: " + getDot();
++ AssertionError ae;
++ ae = new AssertionError("Unexpected bad caret location: " + dot);
++ ae.initCause(e);
++ throw ae;
+ }
+ if (area != null)
+ damage(area);
+@@ -870,26 +906,19 @@
+ if (v != visible)
+ {
+ visible = v;
+- if (visible)
+- if (textComponent.isEnabled() && textComponent.isEditable())
+- {
+- if (blinkTimer == null)
+- initBlinkTimer();
+- blinkTimer.start();
+- }
+- else
+- {
+- if (blinkTimer != null)
+- blinkTimer.stop();
+- }
++ updateTimerStatus();
+ Rectangle area = null;
++ int dot = getDot();
+ try
+ {
+- area = getComponent().modelToView(getDot());
++ area = getComponent().modelToView(dot);
+ }
+- catch (BadLocationException ex)
++ catch (BadLocationException e)
+ {
+- assert false: "Unexpected bad caret location: " + getDot();
++ AssertionError ae;
++ ae = new AssertionError("Unexpected bad caret location: " + dot);
++ ae.initCause(e);
++ throw ae;
+ }
+ if (area != null)
+ damage(area);
+Index: libjava/classpath/javax/swing/text/View.java
+===================================================================
+--- libjava/classpath/javax/swing/text/View.java (revision 111438)
++++ libjava/classpath/javax/swing/text/View.java (working copy)
+@@ -447,9 +447,11 @@
+ protected void updateLayout(DocumentEvent.ElementChange ec,
+ DocumentEvent ev, Shape shape)
+ {
+- Rectangle b = shape.getBounds();
+- if (ec != null)
+- preferenceChanged(this, true, true);
++ if (ec != null && shape != null)
++ preferenceChanged(null, true, true);
++ Container c = getContainer();
++ if (c != null)
++ c.repaint();
+ }
+
+ /**
+@@ -599,9 +601,9 @@
+ * Returns the document position that is (visually) nearest to the given
+ * document position pos
in the given direction d
.
+ *
+- * @param c the text component
+ * @param pos the document position
+ * @param b the bias for pos
++ * @param a the allocation for this view
+ * @param d the direction, must be either {@link SwingConstants#NORTH},
+ * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or
+ * {@link SwingConstants#EAST}
+@@ -615,9 +617,31 @@
+ *
+ * @throws BadLocationException if pos
is not a valid offset in
+ * the document model
++ * @throws IllegalArgumentException if d
is not a valid direction
+ */
+- public abstract int getNextVisualPositionFrom(JTextComponent c, int pos,
+- Position.Bias b, int d,
+- Position.Bias[] biasRet)
+- throws BadLocationException;
++ public int getNextVisualPositionFrom(int pos, Position.Bias b,
++ Shape a, int d,
++ Position.Bias[] biasRet)
++ throws BadLocationException
++ {
++ int ret = pos;
++ switch (d)
++ {
++ case WEST:
++ ret = pos - 1;
++ break;
++ case EAST:
++ ret = pos + 1;
++ break;
++ case NORTH:
++ // TODO: Implement this
++ break;
++ case SOUTH:
++ // TODO: Implement this
++ break;
++ default:
++ throw new IllegalArgumentException("Illegal value for d");
++ }
++ return ret;
++ }
+ }
+Index: libjava/classpath/javax/swing/text/MaskFormatter.java
+===================================================================
+--- libjava/classpath/javax/swing/text/MaskFormatter.java (revision 0)
++++ libjava/classpath/javax/swing/text/MaskFormatter.java (revision 0)
+@@ -0,0 +1,583 @@
++/* MaskFormatter.java --
++ Copyright (C) 2005 Free Software Foundation, Inc.
++
++This file is part of GNU Classpath.
++
++GNU Classpath is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU Classpath is distributed in the hope that it will be useful, but
++WITHOUT 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 GNU Classpath; see the file COPYING. If not, write to the
++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++02110-1301 USA.
++
++Linking this library statically or dynamically with other modules is
++making a combined work based on this library. Thus, the terms and
++conditions of the GNU General Public License cover the whole
++combination.
++
++As a special exception, the copyright holders of this library give you
++permission to link this library with independent modules to produce an
++executable, regardless of the license terms of these independent
++modules, and to copy and distribute the resulting executable under
++terms of your choice, provided that you also meet, for each linked
++independent module, the terms and conditions of the license of that
++module. An independent module is a module which is not derived from
++or based on this library. If you modify this library, you may extend
++this exception to your version of the library, but you are not
++obligated to do so. If you do not wish to do so, delete this
++exception statement from your version. */
++
++
++package javax.swing.text;
++
++import java.text.ParseException;
++
++import javax.swing.JFormattedTextField;
++
++/**
++ * @author Anthony Balkissoon abalkiss at redhat dot com
++ *
++ */
++public class MaskFormatter extends DefaultFormatter
++{
++ // The declaration of the valid mask characters
++ private static final char NUM_CHAR = '#';
++ private static final char ESCAPE_CHAR = '\'';
++ private static final char UPPERCASE_CHAR = 'U';
++ private static final char LOWERCASE_CHAR = 'L';
++ private static final char ALPHANUM_CHAR = 'A';
++ private static final char LETTER_CHAR = '?';
++ private static final char ANYTHING_CHAR = '*';
++ private static final char HEX_CHAR = 'H';
++
++ /** The mask for this MaskFormatter **/
++ private String mask;
++
++ /**
++ * A String made up of the characters that are not valid for input for
++ * this MaskFormatter.
++ */
++ private String invalidChars;
++
++ /**
++ * A String made up of the characters that are valid for input for
++ * this MaskFormatter.
++ */
++ private String validChars;
++
++ /** A String used in place of missing chracters if the value does not
++ * completely fill in the spaces in the mask.
++ */
++ private String placeHolder;
++
++ /** A character used in place of missing characters if the value does
++ * not completely fill in the spaces in the mask.
++ */
++ private char placeHolderChar = ' ';
++
++ /**
++ * Whether or not stringToValue should return literal characters in the mask.
++ */
++ private boolean valueContainsLiteralCharacters = true;
++
++ /** A String used for easy access to valid HEX characters **/
++ private static String hexString = "0123456789abcdefABCDEF";
++
++ /** An int to hold the length of the mask, accounting for escaped characters **/
++ int maskLength = 0;
++
++ public MaskFormatter ()
++ {
++ // Override super's default behaviour, in MaskFormatter the default
++ // is not to allow invalid values
++ setAllowsInvalid(false);
++ }
++
++ /**
++ * Creates a MaskFormatter with the specified mask.
++ * @specnote doesn't actually throw a ParseException although it
++ * is declared to do so
++ * @param mask
++ * @throws java.text.ParseException
++ */
++ public MaskFormatter (String mask) throws java.text.ParseException
++ {
++ // Override super's default behaviour, in MaskFormatter the default
++ // is not to allow invalid values
++ setAllowsInvalid(false);
++ setMask (mask);
++ }
++
++ /**
++ * Returns the mask used in this MaskFormatter.
++ * @return the mask used in this MaskFormatter.
++ */
++ public String getMask()
++ {
++ return mask;
++ }
++
++ /**
++ * Returns a String containing the characters that are not valid for input
++ * for this MaskFormatter.
++ * @return a String containing the invalid characters.
++ */
++ public String getInvalidCharacters()
++ {
++ return invalidChars;
++ }
++
++ /**
++ * Sets characters that are not valid for input. If
++ * invalidCharacters
is non-null then no characters contained
++ * in it will be allowed to be input.
++ *
++ * @param invalidCharacters the String specifying invalid characters.
++ */
++ public void setInvalidCharacters (String invalidCharacters)
++ {
++ this.invalidChars = invalidCharacters;
++ }
++
++ /**
++ * Returns a String containing the characters that are valid for input
++ * for this MaskFormatter.
++ * @return a String containing the valid characters.
++ */
++ public String getValidCharacters()
++ {
++ return validChars;
++ }
++
++ /**
++ * Sets characters that are valid for input. If
++ * validCharacters
is non-null then no characters that are
++ * not contained in it will be allowed to be input.
++ *
++ * @param validCharacters the String specifying valid characters.
++ */
++ public void setValidCharacters (String validCharacters)
++ {
++ this.validChars = validCharacters;
++ }
++
++ /**
++ * Returns the place holder String that is used in place of missing
++ * characters when the value doesn't completely fill in the spaces
++ * in the mask.
++ * @return the place holder String.
++ */
++ public String getPlaceholder()
++ {
++ return placeHolder;
++ }
++
++ /**
++ * Sets the string to use if the value does not completely fill in the mask.
++ * If this is null, the place holder character will be used instead.
++ * @param placeholder the String to use if the value doesn't completely
++ * fill in the mask.
++ */
++ public void setPlaceholder (String placeholder)
++ {
++ this.placeHolder = placeholder;
++ }
++
++ /**
++ * Returns the character used in place of missing characters when the
++ * value doesn't completely fill the mask.
++ * @return the place holder character
++ */
++ public char getPlaceholderCharacter()
++ {
++ return placeHolderChar;
++ }
++
++ /**
++ * Sets the char to use if the value does not completely fill in the mask.
++ * This is only used if the place holder String has not been set or does
++ * not completely fill in the mask.
++ * @param placeholder the char to use if the value doesn't completely
++ * fill in the mask.
++ */
++ public void setPlaceholderCharacter (char placeholder)
++ {
++ this.placeHolderChar = placeholder;
++ }
++
++ /**
++ * Returns true if stringToValue should return the literal
++ * characters in the mask.
++ * @return true if stringToValue should return the literal
++ * characters in the mask
++ */
++ public boolean getValueContainsLiteralCharacters()
++ {
++ return valueContainsLiteralCharacters;
++ }
++
++ /**
++ * Determines whether stringToValue will return literal characters or not.
++ * @param containsLiteralChars if true, stringToValue will return the
++ * literal characters in the mask, otherwise it will not.
++ */
++ public void setValueContainsLiteralCharacters (boolean containsLiteralChars)
++ {
++ this.valueContainsLiteralCharacters = containsLiteralChars;
++ }
++
++ /**
++ * Sets the mask for this MaskFormatter.
++ * @specnote doesn't actually throw a ParseException even though it is
++ * declared to do so
++ * @param mask the new mask for this MaskFormatter
++ * @throws ParseException if mask
is not valid.
++ */
++ public void setMask (String mask) throws ParseException
++ {
++ this.mask = mask;
++
++ // Update the cached maskLength.
++ int end = mask.length() - 1;
++ maskLength = 0;
++ for (int i = 0; i <= end; i++)
++ {
++ // Handle escape characters properly - they don't add to the maskLength
++ // but 2 escape characters in a row is really one escape character and
++ // one literal single quote, so that does add 1 to the maskLength.
++ if (mask.charAt(i) == '\'')
++ {
++ // Escape characters at the end of the mask don't do anything.
++ if (i != end)
++ maskLength++;
++ i++;
++ }
++ else
++ maskLength++;
++ }
++ }
++
++ /**
++ * Installs this MaskFormatter on the JFormattedTextField.
++ * Invokes valueToString to convert the current value from the
++ * JFormattedTextField to a String, then installs the Actions from
++ * getActions, the DocumentFilter from getDocumentFilter, and the
++ * NavigationFilter from getNavigationFilter.
++ *
++ * If valueToString throws a ParseException, this method sets the text
++ * to an empty String and marks the JFormattedTextField as invalid.
++ */
++ public void install (JFormattedTextField ftf)
++ {
++ super.install(ftf);
++ if (ftf != null)
++ {
++ try
++ {
++ valueToString(ftf.getValue());
++ }
++ catch (ParseException pe)
++ {
++ // Set the text to an empty String and mark the JFormattedTextField
++ // as invalid.
++ ftf.setText("");
++ setEditValid(false);
++ }
++ }
++ }
++
++ /**
++ * Parses the text using the mask, valid characters, and invalid characters
++ * to determine the appropriate Object to return. This strips the literal
++ * characters if necessary and invokes super.stringToValue. If the paramter
++ * is invalid for the current mask and valid/invalid character sets this
++ * method will throw a ParseException.
++ *
++ * @param value the String to parse
++ * @throws ParseException if value doesn't match the mask and valid/invalid
++ * character sets
++ */
++ public Object stringToValue (String value) throws ParseException
++ {
++ int vLength = value.length();
++
++ // For value to be a valid it must be the same length as the mask
++ // note this doesn't take into account symbols that occupy more than
++ // one character, this is something we may possibly need to fix.
++ if (maskLength != vLength)
++ throw new ParseException ("stringToValue passed invalid value", vLength);
++
++ // Check if the value is valid according to the mask and valid/invalid
++ // sets.
++ try
++ {
++ convertValue(value, false);
++ }
++ catch (ParseException pe)
++ {
++ throw new ParseException("stringToValue passed invalid value",
++ pe.getErrorOffset());
++ }
++
++ if (!getValueContainsLiteralCharacters())
++ value = stripLiterals(value);
++ return super.stringToValue(value);
++ }
++
++ /**
++ * Strips the literal characters from the given String.
++ * @param value the String to strip
++ * @return the stripped String
++ */
++ String stripLiterals(String value)
++ {
++ StringBuffer result = new StringBuffer();
++ for (int i = 0; i < value.length(); i++)
++ {
++ // Only append the characters that don't correspond to literal
++ // characters in the mask.
++ switch (mask.charAt(i))
++ {
++ case NUM_CHAR:
++ case UPPERCASE_CHAR:
++ case LOWERCASE_CHAR:
++ case ALPHANUM_CHAR:
++ case LETTER_CHAR:
++ case HEX_CHAR:
++ case ANYTHING_CHAR:
++ result.append(value.charAt(i));
++ break;
++ default:
++ }
++ }
++ return result.toString();
++ }
++
++ /**
++ * Returns a String representation of the Object value based on the mask.
++ *
++ * @param value the value to convert
++ * @throws ParseException if value is invalid for this mask and valid/invalid
++ * character sets
++ */
++ public String valueToString (Object value) throws ParseException
++ {
++ String result = super.valueToString(value);
++ int rLength = result.length();
++
++ // If value is longer than the mask, truncate it. Note we may need to
++ // account for symbols that are more than one character long.
++ if (rLength > maskLength)
++ result = result.substring(0, maskLength);
++
++ // Verify the validity and convert to upper/lowercase as needed.
++ result = convertValue(result, true);
++ if (rLength < maskLength)
++ return pad(result, rLength);
++ return result;
++ }
++
++ /**
++ * This method takes in a String and runs it through the mask to make
++ * sure that it is valid. If convert
is true, it also
++ * converts letters to upper/lowercase as required by the mask.
++ * @param value the String to convert
++ * @param convert true if we should convert letters to upper/lowercase
++ * @return the converted String
++ * @throws ParseException if the given String isn't valid for the mask
++ */
++ String convertValue(String value, boolean convert) throws ParseException
++ {
++ StringBuffer result = new StringBuffer(value);
++ char markChar;
++ char resultChar;
++ boolean literal;
++
++ // this boolean is specifically to avoid calling the isCharValid method
++ // when neither invalidChars or validChars has been set
++ boolean checkCharSets = (invalidChars != null || validChars != null);
++
++ for (int i = 0, j = 0; i < value.length(); i++, j++)
++ {
++ literal = false;
++ resultChar = result.charAt(i);
++ // This switch block on the mask character checks that the character
++ // within value
at that point is valid according to the
++ // mask and also converts to upper/lowercase as needed.
++ switch (mask.charAt(j))
++ {
++ case NUM_CHAR:
++ if (!Character.isDigit(resultChar))
++ throw new ParseException("Number expected", i);
++ break;
++ case UPPERCASE_CHAR:
++ if (!Character.isLetter(resultChar))
++ throw new ParseException("Letter expected", i);
++ if (convert)
++ result.setCharAt(i, Character.toUpperCase(resultChar));
++ break;
++ case LOWERCASE_CHAR:
++ if (!Character.isLetter(resultChar))
++ throw new ParseException("Letter expected", i);
++ if (convert)
++ result.setCharAt(i, Character.toLowerCase(resultChar));
++ break;
++ case ALPHANUM_CHAR:
++ if (!Character.isLetterOrDigit(resultChar))
++ throw new ParseException("Letter or number expected", i);
++ break;
++ case LETTER_CHAR:
++ if (!Character.isLetter(resultChar))
++ throw new ParseException("Letter expected", i);
++ break;
++ case HEX_CHAR:
++ if (hexString.indexOf(resultChar) == -1)
++ throw new ParseException("Hexadecimal character expected", i);
++ break;
++ case ANYTHING_CHAR:
++ break;
++ case ESCAPE_CHAR:
++ // Escape character, check the next character to make sure that
++ // the literals match
++ j++;
++ literal = true;
++ if (resultChar != mask.charAt(j))
++ throw new ParseException ("Invalid character: "+resultChar, i);
++ break;
++ default:
++ literal = true;
++ if (!getValueContainsLiteralCharacters() && convert)
++ throw new ParseException ("Invalid character: "+resultChar, i);
++ else if (resultChar != mask.charAt(j))
++ throw new ParseException ("Invalid character: "+resultChar, i);
++ }
++ // If necessary, check if the character is valid.
++ if (!literal && checkCharSets && !isCharValid(resultChar))
++ throw new ParseException("invalid character: "+resultChar, i);
++
++ }
++ return result.toString();
++ }
++
++ /**
++ * Convenience method used by many other methods to check if a character is
++ * valid according to the mask, the validChars, and the invalidChars. To
++ * be valid a character must:
++ * 1. be allowed by the mask
++ * 2. be present in any non-null validChars String
++ * 3. not be present in any non-null invalidChars String
++ * @param testChar the character to test
++ * @return true if the character is valid
++ */
++ boolean isCharValid(char testChar)
++ {
++ char lower = Character.toLowerCase(testChar);
++ char upper = Character.toUpperCase(testChar);
++ // If validChars isn't null, the character must appear in it.
++ if (validChars != null)
++ if (validChars.indexOf(lower) == -1 && validChars.indexOf(upper) == -1)
++ return false;
++ // If invalidChars isn't null, the character must not appear in it.
++ if (invalidChars != null)
++ if (invalidChars.indexOf(lower) != -1
++ || invalidChars.indexOf(upper) != -1)
++ return false;
++ return true;
++ }
++
++ /**
++ * Pads the value with literals, the placeholder String and/or placeholder
++ * character as appropriate.
++ * @param value the value to pad
++ * @param currLength the current length of the value
++ * @return the padded String
++ */
++ String pad (String value, int currLength)
++ {
++ StringBuffer result = new StringBuffer(value);
++ int index = currLength;
++ while (result.length() < maskLength)
++ {
++ // The character used to pad may be a literal, a character from the
++ // place holder string, or the place holder character. getPadCharAt
++ // will find the proper one for us.
++ result.append (getPadCharAt(index));
++ index++;
++ }
++ return result.toString();
++ }
++
++ /**
++ * Returns the character with which to pad the value at the given index
++ * position. If the mask has a literal at this position, this is returned
++ * otherwise if the place holder string is initialized and is longer than
++ * i
characters then the character at position i
++ * from this String is returned. Else, the place holder character is
++ * returned.
++ * @param i the index at which we want to pad the value
++ * @return the character with which we should pad the value
++ */
++ char getPadCharAt(int i)
++ {
++ boolean escaped = false;
++ int target = i;
++ char maskChar;
++ int holderLength = placeHolder == null ? -1 : placeHolder.length();
++ // We must iterate through the mask from the beginning, because the given
++ // index doesn't account for escaped characters. For example, with the
++ // mask "1A'A''A1" index 2 refers to the literalized A, not to the
++ // single quotation.
++ for (int n = 0; n < mask.length(); n++)
++ {
++ maskChar = mask.charAt(n);
++ if (maskChar == ESCAPE_CHAR && !escaped)
++ {
++ target++;
++ escaped = true;
++ }
++ else if (escaped == true)
++ {
++ // Check if target == n which means we've come to the character
++ // we want to return and since it is a literal (because escaped
++ // is true), we return it.
++ if (target == n)
++ return maskChar;
++ escaped = false;
++ }
++ if (target == n)
++ {
++ // We've come to the character we want to return. It wasn't
++ // escaped so if it isn't a literal we should return either
++ // the character from place holder string or the place holder
++ // character, depending on whether or not the place holder
++ // string is long enough.
++ switch (maskChar)
++ {
++ case NUM_CHAR:
++ case UPPERCASE_CHAR:
++ case LOWERCASE_CHAR:
++ case ALPHANUM_CHAR:
++ case LETTER_CHAR:
++ case HEX_CHAR:
++ case ANYTHING_CHAR:
++ if (holderLength > i)
++ return placeHolder.charAt(i);
++ else
++ return placeHolderChar;
++ default:
++ return maskChar;
++ }
++ }
++ }
++ // This shouldn't happen
++ throw new AssertionError("MaskFormatter.getMaskCharAt failed");
++ }
++}
+Index: libjava/classpath/javax/swing/text/WrappedPlainView.java
+===================================================================
+--- libjava/classpath/javax/swing/text/WrappedPlainView.java (revision 111438)
++++ libjava/classpath/javax/swing/text/WrappedPlainView.java (working copy)
+@@ -620,36 +620,6 @@
+ currLineStart = currLineEnd;
+ }
+ }
+-
+- /**
+- * Returns the document position that is (visually) nearest to the given
+- * document position pos
in the given direction d
.
+- *
+- * @param c the text component
+- * @param pos the document position
+- * @param b the bias for pos
+- * @param d the direction, must be either {@link SwingConstants#NORTH},
+- * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or
+- * {@link SwingConstants#EAST}
+- * @param biasRet an array of {@link Position.Bias} that can hold at least
+- * one element, which is filled with the bias of the return position
+- * on method exit
+- *
+- * @return the document position that is (visually) nearest to the given
+- * document position pos
in the given direction
+- * d
+- *
+- * @throws BadLocationException if pos
is not a valid offset
+- * in the document model
+- */
+- public int getNextVisualPositionFrom(JTextComponent c, int pos,
+- Position.Bias b, int d,
+- Position.Bias[] biasRet)
+- throws BadLocationException
+- {
+- // TODO: Implement this properly.
+- throw new AssertionError("Not implemented yet.");
+- }
+
+ /**
+ * This method is called from insertUpdate and removeUpdate.
+Index: libjava/classpath/javax/swing/text/JTextComponent.java
+===================================================================
+--- libjava/classpath/javax/swing/text/JTextComponent.java (revision 111438)
++++ libjava/classpath/javax/swing/text/JTextComponent.java (working copy)
+@@ -380,12 +380,18 @@
+ public KeyStroke[] allKeys()
+ {
+ KeyStroke[] superKeys = super.allKeys();
+- KeyStroke[] mapKeys = map.getBoundKeyStrokes();
+- KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+- for (int i = 0; i < superKeys.length; ++i)
++ KeyStroke[] mapKeys = map.getBoundKeyStrokes();
++ int skl = 0;
++ int mkl = 0;
++ if (superKeys != null)
++ skl = superKeys.length;
++ if (mapKeys != null)
++ mkl = mapKeys.length;
++ KeyStroke[] bothKeys = new KeyStroke[skl + mkl];
++ for (int i = 0; i < skl; ++i)
+ bothKeys[i] = superKeys[i];
+- for (int i = 0; i < mapKeys.length; ++i)
+- bothKeys[i + superKeys.length] = mapKeys[i];
++ for (int i = 0; i < mkl; ++i)
++ bothKeys[i + skl] = mapKeys[i];
+ return bothKeys;
+ }
+ }
+@@ -864,7 +870,7 @@
+ Hashtable acts = new Hashtable(actions.length);
+ for (int i = 0; i < actions.length; ++i)
+ acts.put(actions[i].getValue(Action.NAME), actions[i]);
+- for (int i = 0; i < bindings.length; ++i)
++ for (int i = 0; i < bindings.length; ++i)
+ if (acts.containsKey(bindings[i].actionName))
+ map.addActionForKeyStroke(bindings[i].key, (Action) acts.get(bindings[i].actionName));
+ }
+@@ -906,33 +912,16 @@
+ public JTextComponent()
+ {
+ Keymap defkeymap = getKeymap(DEFAULT_KEYMAP);
+- boolean creatingKeymap = false;
+ if (defkeymap == null)
+ {
+ defkeymap = addKeymap(DEFAULT_KEYMAP, null);
+ defkeymap.setDefaultAction(new DefaultEditorKit.DefaultKeyTypedAction());
+- creatingKeymap = true;
+ }
+
+ setFocusable(true);
+ setEditable(true);
+ enableEvents(AWTEvent.KEY_EVENT_MASK);
+ updateUI();
+-
+- // need to do this after updateUI()
+- if (creatingKeymap)
+- loadKeymap(defkeymap,
+- new KeyBinding[] {
+- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
+- DefaultEditorKit.backwardAction),
+- new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
+- DefaultEditorKit.forwardAction),
+- new KeyBinding(KeyStroke.getKeyStroke("typed \b"),
+- DefaultEditorKit.deletePrevCharAction),
+- new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"),
+- DefaultEditorKit.deleteNextCharAction)
+- },
+- getActions());
+ }
+
+ public void setDocument(Document newDoc)
+Index: libjava/classpath/javax/swing/text/DefaultFormatterFactory.java
+===================================================================
+--- libjava/classpath/javax/swing/text/DefaultFormatterFactory.java (revision 0)
++++ libjava/classpath/javax/swing/text/DefaultFormatterFactory.java (revision 0)
+@@ -0,0 +1,280 @@
++/* DefaultFormatterFactory.java -- FIXME: briefly describe file purpose
++ Copyright (C) 2005 Free Software Foundation, Inc.
++
++This file is part of GNU Classpath.
++
++GNU Classpath is free software; you can redistribute it and/or modify
++it under the terms of the GNU General Public License as published by
++the Free Software Foundation; either version 2, or (at your option)
++any later version.
++
++GNU Classpath is distributed in the hope that it will be useful, but
++WITHOUT 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 GNU Classpath; see the file COPYING. If not, write to the
++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++02110-1301 USA.
++
++Linking this library statically or dynamically with other modules is
++making a combined work based on this library. Thus, the terms and
++conditions of the GNU General Public License cover the whole
++combination.
++
++As a special exception, the copyright holders of this library give you
++permission to link this library with independent modules to produce an
++executable, regardless of the license terms of these independent
++modules, and to copy and distribute the resulting executable under
++terms of your choice, provided that you also meet, for each linked
++independent module, the terms and conditions of the license of that
++module. An independent module is a module which is not derived from
++or based on this library. If you modify this library, you may extend
++this exception to your version of the library, but you are not
++obligated to do so. If you do not wish to do so, delete this
++exception statement from your version. */
++
++
++package javax.swing.text;
++
++import java.io.Serializable;
++
++import javax.swing.JFormattedTextField;
++import javax.swing.JFormattedTextField.AbstractFormatter;
++import javax.swing.JFormattedTextField.AbstractFormatterFactory;
++
++/**
++ * This class is Swing's only concrete implementation of
++ * JFormattedTextField.AbstractFormatterFactory. It holds several
++ * formatters and determines the best one to be used based on the
++ * passed-in value from the text field.
++ *
++ * @author Anthony Balkissoon abalkiss at redhat dot com
++ * @since 1.4
++ */
++public class DefaultFormatterFactory extends AbstractFormatterFactory implements
++ Serializable
++{
++ /**
++ * The default formatter.
++ **/
++ AbstractFormatter defaultFormatter;
++
++ /**
++ * The formatter to use when the JFormattedTextField has focus and either the
++ * value isn't null or the value is null but no nullFormatter
++ * has been specified.
++ */
++ AbstractFormatter editFormatter;
++
++ /**
++ * The formatter to use when the JFormattedTextField doesn't havefocus and
++ * either the value isn't null or the value is null but no
++ * nullFormatter
has been specified.
++ */
++ AbstractFormatter displayFormatter;
++
++ /**
++ * The formatter to use when the value of the JFormattedTextField is null.
++ */
++ AbstractFormatter nullFormatter;
++
++ /**
++ * Creates a DefaultFormatterFactory with no formatters
++ */
++ public DefaultFormatterFactory()
++ {
++ // Nothing to be done here.
++ }
++
++ /**
++ * Creates a new DefaultFormatterFactory with the specified formatters.
++ * @param defaultFormat the formatter to use if no other appropriate non-null
++ * formatted can be found.
++ */
++ public DefaultFormatterFactory(AbstractFormatter defaultFormat)
++ {
++ defaultFormatter = defaultFormat;
++ }
++
++ /**
++ * Creates a new DefaultFormatterFactory with the specified formatters.
++ * @param defaultFormat the formatter to use if no other appropriate non-null
++ * formatted can be found.
++ * @param displayFormat the formatter to use if the JFormattedTextField
++ * doesn't have focus and either the value is not null or the value is null
++ * but no nullFormatter
has been specified.
++ */
++ public DefaultFormatterFactory(AbstractFormatter defaultFormat,
++ AbstractFormatter displayFormat)
++ {
++ defaultFormatter = defaultFormat;
++ displayFormatter = displayFormat;
++ }
++
++ /**
++ * Creates a new DefaultFormatterFactory with the specified formatters.
++ * @param defaultFormat the formatter to use if no other appropriate non-null
++ * formatted can be found.
++ * @param displayFormat the formatter to use if the JFormattedTextField
++ * doesn't have focus and either the value is not null or the value is null
++ * but no nullFormatter
has been specified.
++ * @param editFormat the formatter to use if the JFormattedTextField has
++ * focus and either the value is not null or the value is null but not
++ * nullFormatter
has been specified.
++ */
++ public DefaultFormatterFactory(AbstractFormatter defaultFormat,
++ AbstractFormatter displayFormat,
++ AbstractFormatter editFormat)
++ {
++ defaultFormatter = defaultFormat;
++ displayFormatter = displayFormat;
++ editFormatter = editFormat;
++ }
++
++ /**
++ * Creates a new DefaultFormatterFactory with the specified formatters.
++ * @param defaultFormat the formatter to use if no other appropriate non-null
++ * formatted can be found.
++ * @param displayFormat the formatter to use if the JFormattedTextField
++ * doesn't have focus and either the value is not null or the value is null
++ * but no nullFormatter
has been specified.
++ * @param editFormat the formatter to use if the JFormattedTextField has
++ * focus and either the value is not null or the value is null but not
++ * nullFormatter
has been specified.
++ * @param nullFormat the formatter to use when the value of the
++ * JFormattedTextField is null.
++ */
++ public DefaultFormatterFactory(AbstractFormatter defaultFormat,
++ AbstractFormatter displayFormat,
++ AbstractFormatter editFormat,
++ AbstractFormatter nullFormat)
++ {
++ defaultFormatter = defaultFormat;
++ displayFormatter = displayFormat;
++ editFormatter = editFormat;
++ nullFormatter = nullFormat;
++ }
++
++ /**
++ * Returns the formatted to be used if no other appropriate non-null
++ * formatter can be found.
++ * @return the formatted to be used if no other appropriate non-null
++ * formatter can be found.
++ */
++ public AbstractFormatter getDefaultFormatter()
++ {
++ return defaultFormatter;
++ }
++
++ /**
++ * Sets the formatted to be used if no other appropriate non-null formatter
++ * can be found.
++ * @param defaultFormatter the formatted to be used if no other appropriate
++ * non-null formatter can be found.
++ */
++ public void setDefaultFormatter(AbstractFormatter defaultFormatter)
++ {
++ this.defaultFormatter = defaultFormatter;
++ }
++
++ /**
++ * Gets the displayFormatter
. This is the formatter to use if
++ * the JFormattedTextField is not being edited and either the value is not
++ * null or the value is null and no nullFormatter
has been
++ * specified.
++ * @return the formatter to use if
++ * the JFormattedTextField is not being edited and either the value is not
++ * null or the value is null and no
nullFormatter
has been
++ * specified.
++ */
++ public AbstractFormatter getDisplayFormatter()
++ {
++ return displayFormatter;
++ }
++
++ /**
++ * Sets the
displayFormatter
. This is the formatter to use if
++ * the JFormattedTextField is not being edited and either the value is not
++ * null or the value is null and no nullFormatter
has been
++ * specified.
++ * @param displayFormatter the formatter to use.
++ */
++ public void setDisplayFormatter(AbstractFormatter displayFormatter)
++ {
++ this.displayFormatter = displayFormatter;
++ }
++
++ /**
++ * Gets the
editFormatter
. This is the formatter to use if the
++ * JFormattedTextField is being edited and either the value is not null or
++ * the value is null and no nullFormatter
has been specified.
++ * @return the formatter to use if the JFormattedTextField is being edited
++ * and the value is not null or the value is null but no nullFormatted has
++ * been specified.
++ */
++ public AbstractFormatter getEditFormatter()
++ {
++ return editFormatter;
++ }
++
++ /**
++ * Sets the
editFormatter
. This is the formatter to use if the
++ * JFormattedTextField is being edited and either the value is not null or
++ * the value is null and no nullFormatter
has been specified.
++ * @param editFormatter the formatter to use.
++ */
++ public void setEditFormatter(AbstractFormatter editFormatter)
++ {
++ this.editFormatter = editFormatter;
++ }
++
++ /**
++ * Gets the formatter to use if the value of the JFormattedTextField is null.
++ * @return the formatter to use for null values.
++ */
++ public AbstractFormatter getNullFormatter()
++ {
++ return nullFormatter;
++ }
++
++ /**
++ * Sets the
nullFormatter
. This is the formatter to use if the
++ * value of the JFormattedTextField is null.
++ * @param nullFormatter the formatter to use for null values.
++ */
++ public void setNullFormatter(AbstractFormatter nullFormatter)
++ {
++ this.nullFormatter = nullFormatter;
++ }
++
++ /**
++ * Returns the appropriate formatter based on the state of
++ * tf
. If tf
is null we return null, otherwise
++ * we return one of the following:
++ * 1. Returns
nullFormatter
if tf.getValue()
is
++ * null and nullFormatter
is not.
++ * 2. Returns editFormatter
if tf.hasFocus()
is
++ * true and editFormatter
is not null.
++ * 3. Returns displayFormatter
if tf.hasFocus()
is
++ * false and displayFormatter
is not null.
++ * 4. Otherwise returns defaultFormatter
.
++ */
++ public AbstractFormatter getFormatter(JFormattedTextField tf)
++ {
++ if (tf == null)
++ return null;
++
++ if (tf.getValue() == null && nullFormatter != null)
++ return nullFormatter;
++
++ if (tf.hasFocus() && editFormatter != null)
++ return editFormatter;
++
++ if (!tf.hasFocus() && displayFormatter != null)
++ return displayFormatter;
++
++ return defaultFormatter;
++ }
++}
+Index: libjava/classpath/javax/swing/text/StyleContext.java
+===================================================================
+--- libjava/classpath/javax/swing/text/StyleContext.java (revision 111438)
++++ libjava/classpath/javax/swing/text/StyleContext.java (working copy)
+@@ -362,9 +362,8 @@
+
+ public boolean isEqual(AttributeSet attr)
+ {
+- return attr != null
+- && attr.containsAttributes(this)
+- && this.containsAttributes(attr);
++ return getAttributeCount() == attr.getAttributeCount()
++ && this.containsAttributes(attr);
+ }
+
+ public String toString()
+Index: libjava/classpath/javax/swing/text/IconView.java
+===================================================================
+--- libjava/classpath/javax/swing/text/IconView.java (revision 111438)
++++ libjava/classpath/javax/swing/text/IconView.java (working copy)
+@@ -158,34 +158,4 @@
+ return el.getStartOffset();
+ }
+
+- /**
+- * Returns the document position that is (visually) nearest to the given
+- * document position pos
in the given direction d
.
+- *
+- * @param c the text component
+- * @param pos the document position
+- * @param b the bias for pos
+- * @param d the direction, must be either {@link SwingConstants#NORTH},
+- * {@link SwingConstants#SOUTH}, {@link SwingConstants#WEST} or
+- * {@link SwingConstants#EAST}
+- * @param biasRet an array of {@link Position.Bias} that can hold at least
+- * one element, which is filled with the bias of the return position
+- * on method exit
+- *
+- * @return the document position that is (visually) nearest to the given
+- * document position pos
in the given direction
+- * d
+- *
+- * @throws BadLocationException if pos
is not a valid offset in
+- * the document model
+- */
+- public int getNextVisualPositionFrom(JTextComponent c, int pos,
+- Position.Bias b, int d,
+- Position.Bias[] biasRet)
+- throws BadLocationException
+- {
+- // TODO: Implement this properly.
+- throw new AssertionError("Not implemented yet.");
+- }
+-
+ }
+Index: libjava/classpath/javax/swing/text/html/HTMLDocument.java
+===================================================================
+--- libjava/classpath/javax/swing/text/html/HTMLDocument.java (revision 111438)
++++ libjava/classpath/javax/swing/text/html/HTMLDocument.java (working copy)
+@@ -40,17 +40,32 @@
+
+ import java.net.URL;
+
++import java.io.IOException;
++
++import java.util.HashMap;
++import java.util.Stack;
++import java.util.Vector;
++
++import javax.swing.event.DocumentEvent;
++import javax.swing.event.UndoableEditEvent;
+ import javax.swing.text.AbstractDocument;
+ import javax.swing.text.AttributeSet;
++import javax.swing.text.BadLocationException;
+ import javax.swing.text.DefaultStyledDocument;
+ import javax.swing.text.Element;
+ import javax.swing.text.ElementIterator;
++import javax.swing.text.GapContent;
++import javax.swing.text.MutableAttributeSet;
++import javax.swing.text.SimpleAttributeSet;
++import javax.swing.text.StyleConstants;
+ import javax.swing.text.html.HTML.Tag;
+
+ /**
+- * TODO: This class is not yet completetely implemented.
+- *
++ * TODO: Add more comments here
++ *
+ * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
++ * @author Anthony Balkissoon (abalkiss@redhat.com)
++ * @author Lillian Angel (langel@redhat.com)
+ */
+ public class HTMLDocument extends DefaultStyledDocument
+ {
+@@ -60,8 +75,197 @@
+ public static final String AdditionalComments = "AdditionalComments";
+ URL baseURL = null;
+ boolean preservesUnknownTags = true;
++ int tokenThreshold = Integer.MAX_VALUE;
++ HTMLEditorKit.Parser parser;
++ StyleSheet styleSheet;
++ AbstractDocument.Content content;
+
+ /**
++ * Constructs an HTML document using the default buffer size and a default
++ * StyleSheet.
++ */
++ public HTMLDocument()
++ {
++ this(null);
++ }
++
++ /**
++ * Constructs an HTML document with the default content storage
++ * implementation and the specified style/attribute storage mechanism.
++ *
++ * @param styles - the style sheet
++ */
++ public HTMLDocument(StyleSheet styles)
++ {
++ this(new GapContent(BUFFER_SIZE_DEFAULT), styles);
++ }
++
++ /**
++ * Constructs an HTML document with the given content storage implementation
++ * and the given style/attribute storage mechanism.
++ *
++ * @param c - the document's content
++ * @param styles - the style sheet
++ */
++ public HTMLDocument(AbstractDocument.Content c, StyleSheet styles)
++ {
++ this.content = c;
++ if (styles == null)
++ {
++ styles = new StyleSheet();
++ styles.importStyleSheet(getClass().getResource(HTMLEditorKit.
++ DEFAULT_CSS));
++ }
++ this.styleSheet = styles;
++ }
++
++ /**
++ * Gets the style sheet with the document display rules (CSS) that were specified
++ * in the HTML document.
++ *
++ * @return - the style sheet
++ */
++ public StyleSheet getStyleSheet()
++ {
++ return styleSheet;
++ }
++
++ /**
++ * Replaces the contents of the document with the given element specifications.
++ * This is called before insert if the loading is done in bursts. This is the
++ * only method called if loading the document entirely in one burst.
++ *
++ * @param data - the date that replaces the content of the document
++ */
++ protected void create(DefaultStyledDocument.ElementSpec[] data)
++ {
++ // FIXME: Not implemented
++ System.out.println("create not implemented");
++ super.create(data);
++ }
++
++ /**
++ * This method creates a root element for the new document.
++ *
++ * @return the new default root
++ */
++ protected AbstractDocument.AbstractElement createDefaultRoot()
++ {
++ // FIXME: Not implemented
++ System.out.println("createDefaultRoot not implemented");
++ return super.createDefaultRoot();
++ }
++
++ /**
++ * This method returns an HTMLDocument.RunElement object attached to
++ * parent representing a run of text from p0 to p1. The run has
++ * attributes described by a.
++ *
++ * @param parent - the parent element
++ * @param a - the attributes for the element
++ * @param p0 - the beginning of the range >= 0
++ * @param p1 - the end of the range >= p0
++ * @return the new element
++ */
++ protected Element createLeafElement(Element parent, AttributeSet a, int p0,
++ int p1)
++ {
++ // FIXME: Not implemented
++ System.out.println("createLeafElement not implemented");
++ return super.createLeafElement(parent, a, p0, p1);
++ }
++
++ /** This method returns an HTMLDocument.BlockElement object representing the
++ * attribute set a and attached to parent.
++ *
++ * @param parent - the parent element
++ * @param a - the attributes for the element
++ * @return the new element
++ */
++ protected Element createBranchElement(Element parent, AttributeSet a)
++ {
++ // FIXME: Not implemented
++ System.out.println("createBranchElement not implemented");
++ return super.createBranchElement(parent, a);
++ }
++
++ /**
++ * Inserts new elements in bulk. This is how elements get created in the
++ * document. The parsing determines what structure is needed and creates the
++ * specification as a set of tokens that describe the edit while leaving the
++ * document free of a write-lock. This method can then be called in bursts by
++ * the reader to acquire a write-lock for a shorter duration (i.e. while the
++ * document is actually being altered).
++ *
++ * @param offset - the starting offset
++ * @param data - the element data
++ * @throws BadLocationException - if the given position does not
++ * represent a valid location in the associated document.
++ */
++ protected void insert(int offset, DefaultStyledDocument.ElementSpec[] data)
++ throws BadLocationException
++ {
++ super.insert(offset, data);
++ }
++
++ /**
++ * Updates document structure as a result of text insertion. This will happen
++ * within a write lock. This implementation simply parses the inserted content
++ * for line breaks and builds up a set of instructions for the element buffer.
++ *
++ * @param chng - a description of the document change
++ * @param attr - the attributes
++ */
++ protected void insertUpdate(AbstractDocument.DefaultDocumentEvent chng,
++ AttributeSet attr)
++ {
++ // FIXME: Not implemented
++ System.out.println("insertUpdate not implemented");
++ super.insertUpdate(chng, attr);
++ }
++
++ /**
++ * Returns the parser used by this HTMLDocument to insert HTML.
++ *
++ * @return the parser used by this HTMLDocument to insert HTML.
++ */
++ public HTMLEditorKit.Parser getParser()
++ {
++ return parser;
++ }
++
++ /**
++ * Sets the parser used by this HTMLDocument to insert HTML.
++ *
++ * @param p the parser to use
++ */
++ public void setParser (HTMLEditorKit.Parser p)
++ {
++ parser = p;
++ }
++ /**
++ * Sets the number of tokens to buffer before trying to display the
++ * Document.
++ *
++ * @param n the number of tokens to buffer
++ */
++ public void setTokenThreshold (int n)
++ {
++ tokenThreshold = n;
++ }
++
++ /**
++ * Returns the number of tokens that are buffered before the document
++ * is rendered.
++ *
++ * @return the number of tokens buffered
++ */
++ public int getTokenThreshold ()
++ {
++ return tokenThreshold;
++ }
++
++ /**
+ * Returns the location against which to resolve relative URLs.
+ * This is the document's URL if the document was loaded from a URL.
+ * If a base
tag is found, it will be used.
+@@ -79,7 +283,7 @@
+ public void setBase(URL u)
+ {
+ baseURL = u;
+- //TODO: also set the base of the StyleSheet
++ styleSheet.setBase(u);
+ }
+
+ /**
+@@ -259,10 +463,1133 @@
+ return null;
+ }
+
++ /**
++ * Gets the name of the element.
++ *
++ * @return the name of the element if it exists, null otherwise.
++ */
+ public String getName()
+ {
+- //FIXME: this is supposed to do something different from the super class
+- return super.getName();
++ return (String) getAttribute(StyleConstants.NameAttribute);
+ }
+ }
++
++ /**
++ * RunElement represents a section of text that has a set of
++ * HTML character level attributes assigned to it.
++ */
++ public class RunElement extends AbstractDocument.LeafElement
++ {
++
++ /**
++ * Constructs an element that has no children. It represents content
++ * within the document.
++ *
++ * @param parent - parent of this
++ * @param a - elements attributes
++ * @param start - the start offset >= 0
++ * @param end - the end offset
++ */
++ public RunElement(Element parent, AttributeSet a, int start, int end)
++ {
++ super(parent, a, start, end);
++ }
++
++ /**
++ * Gets the name of the element.
++ *
++ * @return the name of the element if it exists, null otherwise.
++ */
++ public String getName()
++ {
++ return (String) getAttribute(StyleConstants.NameAttribute);
++ }
++
++ /**
++ * Gets the resolving parent. HTML attributes do not inherit at the
++ * model level, so this method returns null.
++ *
++ * @return null
++ */
++ public AttributeSet getResolveParent()
++ {
++ return null;
++ }
++ }
++
++ /**
++ * A reader to load an HTMLDocument with HTML structure.
++ *
++ * @author Anthony Balkissoon abalkiss at redhat dot com
++ */
++ public class HTMLReader extends HTMLEditorKit.ParserCallback
++ {
++ /** Holds the current character attribute set **/
++ protected MutableAttributeSet charAttr = new SimpleAttributeSet();
++
++ protected Vector parseBuffer = new Vector();
++
++ /** A stack for character attribute sets **/
++ Stack charAttrStack = new Stack();
++
++ /** A mapping between HTML.Tag objects and the actions that handle them **/
++ HashMap tagToAction;
++
++ /** Tells us whether we've received the '